mirror of
https://github.com/Instadapp/assembly.git
synced 2024-07-29 22:37:06 +00:00
wip - balances ui
This commit is contained in:
parent
14cb6b7bc2
commit
e0964abe0f
42
components/common/list/List.vue
Normal file
42
components/common/list/List.vue
Normal file
|
@ -0,0 +1,42 @@
|
|||
<template>
|
||||
<div class="flex flex-col flex-grow">
|
||||
<div class="flex flex-col flex-grow">
|
||||
<div v-if="loading" class="flex items-center justify-center">
|
||||
<Spinner class="w-6 h-6" />
|
||||
</div>
|
||||
<div v-else class="flex flex-col flex-grow">
|
||||
<div v-if="items.length" :class="{ ' divide-y divide-grey-light divide-opacity-50': divided }">
|
||||
<div v-for="(item, i) in items" :key="i">
|
||||
<slot name="default" :item="item" :index="i"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex flex-col items-center justify-center flex-grow">
|
||||
<slot name="no-items"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from '@nuxtjs/composition-api'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
divided: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style></style>
|
51
components/common/menu/Menu.vue
Normal file
51
components/common/menu/Menu.vue
Normal file
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<client-only>
|
||||
<v-popover
|
||||
:popover-base-class="baseClass"
|
||||
popover-inner-class="menu-inner"
|
||||
popover-wrapper-class="menu-wrapper"
|
||||
placement="auto-start"
|
||||
offset="8"
|
||||
:delay="delay"
|
||||
>
|
||||
<slot name="activator"> </slot>
|
||||
|
||||
<template slot="popover">
|
||||
<div
|
||||
v-close-popover="closeOnClick"
|
||||
:border-radius="borderRadius"
|
||||
class="flex overflow-hidden border border-opacity-50 shadow-lg border-grey-light dark:bg-dark-400"
|
||||
:class="{ 'py-2': !noPadding }"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
</v-popover>
|
||||
</client-only>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from '@nuxtjs/composition-api'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
closeOnClick: { type: Boolean, default: true },
|
||||
borderRadius: { type: String, default: 'rounded' },
|
||||
noPadding: { type: Boolean, default: false },
|
||||
baseClass: { type: String, default: 'menu' },
|
||||
delay: { type: Object, default: () => ({ show: 100, hide: 200 }) },
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.menu {
|
||||
outline: none;
|
||||
min-width: 200px;
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.v-popover > .trigger {
|
||||
display: initial !important;
|
||||
}
|
||||
</style>
|
20
components/common/menu/MenuButton.vue
Normal file
20
components/common/menu/MenuButton.vue
Normal file
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<Button
|
||||
color="white"
|
||||
class="border rounded-sm border-grey-light dark:border-opacity-25 dark:bg-opacity-100 dark:bg-dark-400"
|
||||
:style="`width: ${size}px; height: ${size}px`"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<Icon name="dots-horizontal" :style="`height: ${+size / 2}`" />
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from '@nuxtjs/composition-api'
|
||||
|
||||
export default defineComponent({
|
||||
props: { size: { type: String, default: '30' } },
|
||||
})
|
||||
</script>
|
||||
|
||||
<style></style>
|
29
components/common/menu/MenuListItem.vue
Normal file
29
components/common/menu/MenuListItem.vue
Normal file
|
@ -0,0 +1,29 @@
|
|||
<template>
|
||||
<div
|
||||
class="flex items-center px-4 py-3 font-semibold transition-colors duration-150 text-12 dark:bg-opacity-17"
|
||||
:class="{
|
||||
'pointer-events-none text-grey-pure': disabled,
|
||||
'cursor-pointer text-ocean-blue-pure hover:bg-ocean-blue-light dark:text-light': !disabled,
|
||||
}"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<div :is="icon" v-if="icon" class="mr-2" :class="{ 'w-5 h-5': largeIcon, 'w-3 h-3': !largeIcon }"></div>
|
||||
<div class="leading-none">
|
||||
{{ item }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from '@nuxtjs/composition-api'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
item: { type: String, required: true },
|
||||
icon: { type: Object },
|
||||
disabled: { type: Boolean, default: false },
|
||||
largeIcon: { type: Boolean, default: false },
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
|
@ -1,7 +1,9 @@
|
|||
<template>
|
||||
<div class="flex-shrink-0 w-full mx-auto p-4">
|
||||
<div class="flex justify-between items-center w-full">
|
||||
<button
|
||||
<div>
|
||||
<button
|
||||
v-if="showBackButton"
|
||||
class="flex items-center justify-center text-opacity-50 group hover:text-opacity-100 focus:hover:text-opacity-100 text-grey-pure focus:outline-none"
|
||||
@click="back"
|
||||
>
|
||||
|
@ -9,6 +11,7 @@
|
|||
class="transition-transform duration-75 ease-out transform group-hover:-translate-x-1"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="flex items-center justify-center text-opacity-50 group hover:text-opacity-100 focus:hover:text-opacity-100 text-grey-pure focus:outline-none"
|
||||
|
@ -31,6 +34,12 @@ import SVGArrowLeft from '@/assets/icons/arrow-left.svg?inline'
|
|||
import { useSidebar } from '~/composables/useSidebar'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
showBackButton: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SVGClose,
|
||||
SVGArrowLeft,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div v-if="filteredAssets.length" class="pb-6">
|
||||
<CardCurrency
|
||||
<card-currency
|
||||
v-for="token in filteredAssets"
|
||||
:key="token.address"
|
||||
class="mt-2 sm:mt-4 first:mt-0"
|
||||
|
@ -20,19 +20,21 @@
|
|||
|
||||
<script>
|
||||
import { computed, defineComponent, watchEffect } from '@nuxtjs/composition-api'
|
||||
import { useBalances } from '~/composables/useBalances'
|
||||
import { useSearchFilter } from '~/composables/useSearchFilter'
|
||||
import { useToken } from '~/composables/useToken'
|
||||
import CardCurrency from '../overview/CardCurrency.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: { CardCurrency },
|
||||
props: {
|
||||
search: { type: String, default: null },
|
||||
type: { type: String },
|
||||
actionLabel: { type: String, required: true },
|
||||
},
|
||||
setup(props) {
|
||||
const { assets } = useToken()
|
||||
const { getAssets } = useBalances()
|
||||
|
||||
const typedAssets = computed(() => assets.value(props.type))
|
||||
const typedAssets = computed(() => getAssets(props.type))
|
||||
|
||||
const { filtered: filteredAssets, search } = useSearchFilter(typedAssets, 'name', 'symbol')
|
||||
watchEffect(() => (search.value = props.search))
|
||||
|
|
31
components/sidebar/context/overview/CardCurrency.vue
Normal file
31
components/sidebar/context/overview/CardCurrency.vue
Normal file
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<div class="flex items-center px-4 py-4 select-none dark:bg-dark-400">
|
||||
<IconCurrency :currency="tokenKey" />
|
||||
<div class="flex flex-col px-4">
|
||||
<div class="mb-1 font-semibold whitespace-no-wrap text-12 text-navi-pure dark:text-light">
|
||||
{{ formatDecimal(balance) }} {{ symbol }}
|
||||
</div>
|
||||
<div class="font-medium whitespace-no-wrap text-12 text-grey-pure">{{ formatUsd(netWorth, 2) }}</div>
|
||||
</div>
|
||||
<Button class="ml-auto w-18" color="ocean-blue" @click="$emit('action')">{{ actionLabel }}</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from '@nuxtjs/composition-api'
|
||||
import { useFormatting } from '~/composables/useFormatting'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
tokenKey: { type: String, required: true },
|
||||
symbol: { type: String, required: true },
|
||||
balance: { type: String, required: true },
|
||||
netWorth: { type: String, required: true },
|
||||
actionLabel: { type: String, required: true },
|
||||
},
|
||||
setup() {
|
||||
const { formatUsd, formatDecimal } = useFormatting()
|
||||
return { formatUsd, formatDecimal }
|
||||
},
|
||||
})
|
||||
</script>
|
90
components/sidebar/context/overview/SidebarOverview.vue
Normal file
90
components/sidebar/context/overview/SidebarOverview.vue
Normal file
|
@ -0,0 +1,90 @@
|
|||
<template>
|
||||
<SidebarContextContainer class="flex-1 h-full overflow-hidden">
|
||||
<SidebarContextHeader :showBackButton="false"></SidebarContextHeader>
|
||||
|
||||
<div class="flex-grow overflow-y-scroll scrollbar-hover">
|
||||
<div class="h-full mx-auto" style="max-width: 296px">
|
||||
<div class="flex flex-col h-full py-2 sm:py-4">
|
||||
<SidebarOverviewBalance />
|
||||
<div class="flex flex-col flex-grow mt-2 sm:mt-4">
|
||||
<div class="flex flex-shrink-0">
|
||||
<search-input
|
||||
v-model.trim="search"
|
||||
placeholder="Search Currency"
|
||||
class="mr-2"
|
||||
/>
|
||||
<Menu>
|
||||
<template v-slot:activator="{ on }">
|
||||
<menu-button size="38" v-on="on" />
|
||||
</template>
|
||||
<template>
|
||||
<list :items="menuActions">
|
||||
<template v-slot:default="{ item }">
|
||||
<menu-list-item
|
||||
:item="item.text"
|
||||
:icon="item.icon"
|
||||
:disabled="item.disabled"
|
||||
@click="item.onClick"
|
||||
></menu-list-item>
|
||||
</template>
|
||||
</list>
|
||||
</template>
|
||||
</Menu>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col flex-grow mt-2 sm:mt-4">
|
||||
<currency-list :search="search" type="dsa" action-label="Trade">
|
||||
<template v-slot:no-items>
|
||||
<div class="flex flex-col">
|
||||
<div class="font-medium text-center text-grey-pure">
|
||||
Can't find existing token?
|
||||
</div>
|
||||
<Button
|
||||
color="ocean-blue"
|
||||
large
|
||||
style="background: none"
|
||||
@click="startAddingCustomToken"
|
||||
>Add custom token</Button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</currency-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarContextContainer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, computed } from '@nuxtjs/composition-api'
|
||||
import SVGAdd from '@/assets/img/icons/add.svg?inline'
|
||||
import CurrencyList from '../components/CurrencyList.vue'
|
||||
import List from '~/components/common/list/List.vue'
|
||||
import Menu from '~/components/common/menu/Menu.vue'
|
||||
import MenuButton from '~/components/common/menu/MenuButton.vue'
|
||||
import MenuListItem from '~/components/common/menu/MenuListItem.vue'
|
||||
|
||||
export default defineComponent({
|
||||
components: { SVGAdd, CurrencyList, List, Menu, MenuButton, MenuListItem },
|
||||
setup() {
|
||||
|
||||
const menuActions = computed(() => [
|
||||
{
|
||||
text: 'Add custom token',
|
||||
onClick: startAddingCustomToken,
|
||||
icon: SVGAdd,
|
||||
disabled: false,
|
||||
},
|
||||
])
|
||||
|
||||
function startAddingCustomToken() {
|
||||
}
|
||||
|
||||
const search = ref(null)
|
||||
|
||||
return { search, menuActions }
|
||||
},
|
||||
})
|
||||
</script>
|
|
@ -0,0 +1,29 @@
|
|||
<template>
|
||||
<div class="flex flex-col items-center flex-shrink-0 w-full px-8 mt-6 mb-2 text-center sm:mb-10">
|
||||
<h3 class="flex items-center leading-none">Balance <Info text="This is your DSA balance and doesn't reflect your wallet balance (like Metamask)" class="ml-1" /></h3>
|
||||
<div class="mt-4 font-semibold text-32">{{ formatUsd(balanceTotal) }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, onMounted } from '@nuxtjs/composition-api'
|
||||
import SVGChevronUp from '@/assets/img/icons/chevron-up.svg'
|
||||
import { useFormatting } from '~/composables/useFormatting'
|
||||
import { useBalances } from '~/composables/useBalances'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
SVGChevronUp,
|
||||
},
|
||||
setup() {
|
||||
const { formatUsd } = useFormatting()
|
||||
const { balanceTotal, fetchBalances, balances, prices } = useBalances()
|
||||
|
||||
onMounted(() => {
|
||||
fetchBalances(true)
|
||||
})
|
||||
|
||||
return { formatUsd, balanceTotal, balances, prices }
|
||||
},
|
||||
})
|
||||
</script>
|
|
@ -1,4 +1,9 @@
|
|||
import { nextTick, onMounted, reactive, watch } from "@nuxtjs/composition-api";
|
||||
import {
|
||||
computed,
|
||||
reactive,
|
||||
onMounted,
|
||||
useContext
|
||||
} from "@nuxtjs/composition-api";
|
||||
import BigNumber from "bignumber.js";
|
||||
import abis from "~/constant/abis";
|
||||
import addresses from "~/constant/addresses";
|
||||
|
@ -11,17 +16,33 @@ import Web3 from "web3";
|
|||
import { AbiItem } from "web3-utils";
|
||||
import { mainnetWeb3, polygonWeb3 } from "~/utils/web3";
|
||||
import { useToken } from "./useToken";
|
||||
import { useBigNumber } from "./useBigNumber";
|
||||
import { useSorting } from "./useSorting";
|
||||
|
||||
const balances = reactive({
|
||||
user: null,
|
||||
dsa: null
|
||||
});
|
||||
|
||||
const prices = reactive({
|
||||
mainnet: {},
|
||||
polygon: {}
|
||||
});
|
||||
|
||||
export function useBalances() {
|
||||
const { account, web3, networkName } = useWeb3();
|
||||
const { $axios } = useContext();
|
||||
const { times, plus, ensureValue } = useBigNumber();
|
||||
const { account, networkName } = useWeb3();
|
||||
const { activeAccount } = useDSA();
|
||||
const { getTokenByKey } = useToken();
|
||||
const { by } = useSorting();
|
||||
|
||||
onMounted(async () => {
|
||||
prices.mainnet = await $axios.$get("https://api.instadapp.io/defi/prices");
|
||||
prices.polygon = await $axios.$get(
|
||||
"https://api.instadapp.io/defi/polygon/prices"
|
||||
);
|
||||
});
|
||||
const fetchBalances = async (refresh = false) => {
|
||||
if (!balances.user || refresh) {
|
||||
balances.user = {
|
||||
|
@ -46,27 +67,57 @@ export function useBalances() {
|
|||
}
|
||||
};
|
||||
|
||||
const getBalanceByKey = (tokenKey, network = null) => {
|
||||
const getBalanceByKey = (tokenKey, network = null, type = "dsa") => {
|
||||
return getBalanceByAddress(getTokenByKey(tokenKey)?.address, network, type);
|
||||
};
|
||||
|
||||
const getBalanceByAddress = (address, network = null, type = "dsa") => {
|
||||
return (
|
||||
balances.dsa?.[network || networkName.value][
|
||||
getTokenByKey(tokenKey)?.address
|
||||
]?.balance || "0"
|
||||
balances[type]?.[network || networkName.value][address]?.balance || "0"
|
||||
);
|
||||
};
|
||||
|
||||
const getBalanceRawByKey = (tokenKey, network = null) => {
|
||||
const getBalanceRawByKey = (tokenKey, network = null, type = "dsa") => {
|
||||
return (
|
||||
balances.dsa?.[network || networkName.value][
|
||||
balances[type]?.[network || networkName.value][
|
||||
getTokenByKey(tokenKey)?.address
|
||||
]?.raw || "0"
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const netWorth = (address, type = "dsa") => {
|
||||
const balance = getBalanceByAddress(address, networkName.value, type);
|
||||
const price = ensureValue(prices[networkName.value][address]).toFixed();
|
||||
|
||||
return times(balance, price).toFixed();
|
||||
};
|
||||
|
||||
const balanceTotal = computed(() =>
|
||||
tokens[networkName.value].allTokens.reduce(
|
||||
(totalNetWorth, token) =>
|
||||
plus(totalNetWorth, netWorth(token.address)).toFixed(),
|
||||
"0"
|
||||
)
|
||||
);
|
||||
|
||||
const getAssets = (type = "dsa") => {
|
||||
return tokens[networkName.value].allTokens
|
||||
.map(token => ({
|
||||
...token,
|
||||
balance: getBalanceByAddress(token.address, networkName.value, type),
|
||||
netWorth: netWorth(token.address, type)
|
||||
}))
|
||||
.sort(by("-netWorth"));
|
||||
};
|
||||
|
||||
return {
|
||||
balances,
|
||||
fetchBalances,
|
||||
getBalanceByKey,
|
||||
getBalanceRawByKey
|
||||
getBalanceRawByKey,
|
||||
balanceTotal,
|
||||
prices,
|
||||
getAssets
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,12 @@ import SidebarAaveV2Borrow from '~/components/sidebar/context/aaveV2/SidebarAave
|
|||
//@ts-ignore
|
||||
import SidebarAaveV2Payback from '~/components/sidebar/context/aaveV2/SidebarAaveV2Payback.vue'
|
||||
|
||||
//@ts-ignore
|
||||
import SidebarOverview from '~/components/sidebar/context/overview/SidebarOverview.vue'
|
||||
|
||||
const sidebars = {
|
||||
"#overview" : {component: SidebarOverview, back : false, close : true },
|
||||
"/polygon/aave-v2": { component: null },
|
||||
"/polygon/aave-v2#overview": { component: null },
|
||||
"/polygon/aave-v2#supply": { component: SidebarAaveV2Supply },
|
||||
"/polygon/aave-v2#borrow": { component: SidebarAaveV2Borrow },
|
||||
"/polygon/aave-v2#payback": { component: SidebarAaveV2Payback },
|
||||
|
@ -32,7 +35,6 @@ const sidebars = {
|
|||
|
||||
|
||||
"/mainnet/aave-v2": { component: null },
|
||||
"/mainnet/aave-v2#overview": { component: null },
|
||||
"/mainnet/aave-v2#supply": { component: SidebarAaveV2Supply },
|
||||
"/mainnet/aave-v2#borrow": { component: SidebarAaveV2Borrow },
|
||||
"/mainnet/aave-v2#payback": { component: SidebarAaveV2Payback },
|
||||
|
@ -68,6 +70,8 @@ export function init() {
|
|||
return
|
||||
}
|
||||
|
||||
console.log(hash, sidebars[route.path + hash], sidebars[hash]);
|
||||
|
||||
sidebar.value = sidebars[route.path + hash] || sidebars[hash];
|
||||
|
||||
if (!sidebar.value) {
|
||||
|
@ -113,11 +117,16 @@ export function useSidebar() {
|
|||
return !!component.value;
|
||||
});
|
||||
|
||||
const showSidebarBalances = () => {
|
||||
router.push({ hash: 'overview' });
|
||||
}
|
||||
|
||||
return {
|
||||
close,
|
||||
back,
|
||||
component,
|
||||
props,
|
||||
isOpen
|
||||
isOpen,
|
||||
showSidebarBalances
|
||||
};
|
||||
}
|
||||
|
|
27
composables/useSorting.ts
Normal file
27
composables/useSorting.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { useBigNumber } from './useBigNumber'
|
||||
|
||||
export function useSorting() {
|
||||
const { times, minus, max } = useBigNumber()
|
||||
|
||||
/**
|
||||
* Return a sorting function for the specified parameter.
|
||||
*
|
||||
* @param {string} sorting Property key for sorting. Prefix with `-` to sort descending.
|
||||
* Property value should be Number or Number in String representation
|
||||
*/
|
||||
function by(sorting) {
|
||||
if (sorting.startsWith('-')) {
|
||||
return (a, b) => minus(b[sorting.substr(1)], a[sorting.substr(1)]).toNumber()
|
||||
} else {
|
||||
return (a, b) => minus(a[sorting], b[sorting]).toNumber()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
by,
|
||||
byMaxSupplyOrBorrowDesc: (a, b) => minus(max(b.supplyUsd, b.borrowUsd), max(a.supplyUsd, a.borrowUsd)).toNumber(),
|
||||
byNetWorthVaultDesc: (a, b) =>
|
||||
minus(minus(times(b.col, b.price), b.debt), minus(times(a.col, a.price), a.debt)).toNumber(),
|
||||
byTotalSupply: (a, b) => minus(b.poolTokenUsd, a.poolTokenUsd).toNumber(),
|
||||
}
|
||||
}
|
|
@ -16,6 +16,36 @@
|
|||
<Modal />
|
||||
|
||||
<NotificationBar />
|
||||
|
||||
<div class="fixed bottom-0 right-0 mr-10 mb-16">
|
||||
<button
|
||||
@click="showSidebarBalances"
|
||||
class="px-9 h-[56px] bg-primary-blue-dark hover:bg-primary-blue-hover text-white rounded-[28px] text-lg font-semibold shadow flex items-center"
|
||||
>
|
||||
<svg
|
||||
class="mr-3"
|
||||
width="14"
|
||||
height="16"
|
||||
viewBox="0 0 14 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0)">
|
||||
<path
|
||||
d="M12.6109 4L2.1875 4C1.94578 4 1.75 3.77625 1.75 3.5C1.75 3.22375 1.94578 3 2.1875 3L12.6875 3C12.9292 3 13.125 2.77625 13.125 2.5C13.125 1.67156 12.5374 1 11.8125 1L1.75 1C0.783399 1 0 1.89531 0 3L0 13C0 14.1047 0.783399 15 1.75 15L12.6109 15C13.3771 15 14 14.3272 14 13.5L14 5.5C14 4.67281 13.3771 4 12.6109 4ZM11.375 10.5C10.8918 10.5 10.5 10.0522 10.5 9.5C10.5 8.94781 10.8918 8.5 11.375 8.5C11.8582 8.5 12.25 8.94781 12.25 9.5C12.25 10.0522 11.8582 10.5 11.375 10.5Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0">
|
||||
<rect width="14" height="16" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
Balance
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -25,7 +55,7 @@ import MakerDAOIcon from '~/assets/icons/makerdao.svg?inline'
|
|||
import CompoundIcon from '~/assets/icons/compound.svg?inline'
|
||||
import AaveIcon from '~/assets/icons/aave.svg?inline'
|
||||
import { useWeb3 } from '~/composables/useWeb3'
|
||||
import { init as initSidebars } from '~/composables/useSidebar'
|
||||
import { init as initSidebars, useSidebar } from '~/composables/useSidebar'
|
||||
import { useBackdrop } from '@/composables/useBackdrop'
|
||||
import { useNetwork } from "~/composables/useNetwork";
|
||||
|
||||
|
@ -40,6 +70,7 @@ export default defineComponent({
|
|||
const { activeNetwork, checkForNetworkMismatch } = useNetwork();
|
||||
const { isShown: isBackdropShown, close: closeBackdrop } = useBackdrop()
|
||||
const { redirect } = useContext()
|
||||
const { showSidebarBalances } = useSidebar()
|
||||
const route = useRoute()
|
||||
|
||||
watch(isBackdropShown, () => {
|
||||
|
@ -62,7 +93,7 @@ export default defineComponent({
|
|||
return;
|
||||
}
|
||||
|
||||
if (!route.value.path.includes(activeNetwork.value.id)) {
|
||||
if (route.value.path.includes(['mainnet', 'polygon']) && route.value.path.includes(activeNetwork.value.id)) {
|
||||
redirect('/')
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
@ -79,6 +110,7 @@ export default defineComponent({
|
|||
deactivate,
|
||||
isBackdropShown,
|
||||
closeBackdrop,
|
||||
showSidebarBalances,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ export default {
|
|||
|
||||
// Modules: https://go.nuxtjs.dev/config-modules
|
||||
modules: [
|
||||
'@nuxtjs/axios',
|
||||
],
|
||||
|
||||
// Build Configuration: https://go.nuxtjs.dev/config-build
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"generate": "nuxt generate"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxtjs/axios": "^5.13.6",
|
||||
"@nuxtjs/composition-api": "^0.24.7",
|
||||
"@portis/web3": "^4.0.5",
|
||||
"@tailwindcss/forms": "^0.3.3",
|
||||
|
|
14
pages/overview.vue
Normal file
14
pages/overview.vue
Normal file
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div>
|
||||
<sidebar-overview />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "@nuxtjs/composition-api";
|
||||
import SidebarOverview from "~/components/sidebar/context/overview/SidebarOverview.vue";
|
||||
|
||||
export default defineComponent({
|
||||
components: {SidebarOverview },
|
||||
});
|
||||
</script>
|
|
@ -26,6 +26,7 @@
|
|||
},
|
||||
"types": [
|
||||
"@nuxt/types",
|
||||
"@nuxtjs/axios",
|
||||
"@types/node"
|
||||
]
|
||||
},
|
||||
|
|
80
yarn.lock
80
yarn.lock
|
@ -1561,6 +1561,17 @@
|
|||
webpack-node-externals "^3.0.0"
|
||||
webpackbar "^4.0.0"
|
||||
|
||||
"@nuxtjs/axios@^5.13.6":
|
||||
version "5.13.6"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/axios/-/axios-5.13.6.tgz#6f4bbd98a3a7799a5d2c0726c6ad2a98aa111881"
|
||||
integrity sha512-XS+pOE0xsDODs1zAIbo95A0LKlilvJi8YW0NoXYuq3/jjxGgWDxizZ6Yx0AIIjZOoGsXJOPc0/BcnSEUQ2mFBA==
|
||||
dependencies:
|
||||
"@nuxtjs/proxy" "^2.1.0"
|
||||
axios "^0.21.1"
|
||||
axios-retry "^3.1.9"
|
||||
consola "^2.15.3"
|
||||
defu "^5.0.0"
|
||||
|
||||
"@nuxtjs/composition-api@^0.24.7":
|
||||
version "0.24.7"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/composition-api/-/composition-api-0.24.7.tgz#76ec3660a03cd7bdb8b85fd31e8dc6a2b7194e8f"
|
||||
|
@ -1582,6 +1593,13 @@
|
|||
consola "^2.15.3"
|
||||
google-fonts-helper "^1.2.0"
|
||||
|
||||
"@nuxtjs/proxy@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/proxy/-/proxy-2.1.0.tgz#fa7715a11d237fa1273503c4e9e137dd1bf5575b"
|
||||
integrity sha512-/qtoeqXgZ4Mg6LRg/gDUZQrFpOlOdHrol/vQYMnKu3aN3bP90UfOUB3QSDghUUK7OISAJ0xp8Ld78aHyCTcKCQ==
|
||||
dependencies:
|
||||
http-proxy-middleware "^1.0.6"
|
||||
|
||||
"@nuxtjs/svg@^0.1.12":
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/svg/-/svg-0.1.12.tgz#a5b2a66070a36e3c5c5183db9e3d89485ef3eb1c"
|
||||
|
@ -1857,6 +1875,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812"
|
||||
integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==
|
||||
|
||||
"@types/http-proxy@^1.17.5":
|
||||
version "1.17.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.7.tgz#30ea85cc2c868368352a37f0d0d3581e24834c6f"
|
||||
integrity sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7":
|
||||
version "7.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818"
|
||||
|
@ -2800,6 +2825,13 @@ aws4@^1.8.0:
|
|||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
||||
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
||||
|
||||
axios-retry@^3.1.9:
|
||||
version "3.1.9"
|
||||
resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.1.9.tgz#6c30fc9aeb4519aebaec758b90ef56fa03fe72e8"
|
||||
integrity sha512-NFCoNIHq8lYkJa6ku4m+V1837TP6lCa7n79Iuf8/AqATAHYB0ISaAS1eyIenDOfHOLtym34W65Sjke2xjg2fsA==
|
||||
dependencies:
|
||||
is-retry-allowed "^1.1.0"
|
||||
|
||||
axios@^0.18.0:
|
||||
version "0.18.1"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3"
|
||||
|
@ -2808,6 +2840,13 @@ axios@^0.18.0:
|
|||
follow-redirects "1.5.10"
|
||||
is-buffer "^2.0.2"
|
||||
|
||||
axios@^0.21.1:
|
||||
version "0.21.1"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
|
||||
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
|
||||
dependencies:
|
||||
follow-redirects "^1.10.0"
|
||||
|
||||
babel-loader@^8.2.2:
|
||||
version "8.2.2"
|
||||
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81"
|
||||
|
@ -5168,7 +5207,7 @@ eventemitter3@4.0.4:
|
|||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384"
|
||||
integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==
|
||||
|
||||
eventemitter3@4.0.7:
|
||||
eventemitter3@4.0.7, eventemitter3@^4.0.0:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
@ -5493,6 +5532,11 @@ follow-redirects@1.5.10:
|
|||
dependencies:
|
||||
debug "=3.1.0"
|
||||
|
||||
follow-redirects@^1.0.0, follow-redirects@^1.10.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
|
||||
integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
@ -6185,6 +6229,26 @@ http-https@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b"
|
||||
integrity sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=
|
||||
|
||||
http-proxy-middleware@^1.0.6:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz#43700d6d9eecb7419bf086a128d0f7205d9eb665"
|
||||
integrity sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==
|
||||
dependencies:
|
||||
"@types/http-proxy" "^1.17.5"
|
||||
http-proxy "^1.18.1"
|
||||
is-glob "^4.0.1"
|
||||
is-plain-obj "^3.0.0"
|
||||
micromatch "^4.0.2"
|
||||
|
||||
http-proxy@^1.18.1:
|
||||
version "1.18.1"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
|
||||
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
|
||||
dependencies:
|
||||
eventemitter3 "^4.0.0"
|
||||
follow-redirects "^1.0.0"
|
||||
requires-port "^1.0.0"
|
||||
|
||||
http-signature@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||
|
@ -6620,6 +6684,11 @@ is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
|
||||
integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
|
||||
|
||||
is-plain-obj@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7"
|
||||
integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==
|
||||
|
||||
is-plain-object@^2.0.3, is-plain-object@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
|
||||
|
@ -6640,7 +6709,7 @@ is-resolvable@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
|
||||
integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
|
||||
|
||||
is-retry-allowed@^1.0.0:
|
||||
is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
|
||||
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
|
||||
|
@ -7468,7 +7537,7 @@ micromatch@^3.1.10, micromatch@^3.1.4:
|
|||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.2"
|
||||
|
||||
micromatch@^4.0.0, micromatch@^4.0.4:
|
||||
micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
||||
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
||||
|
@ -9806,6 +9875,11 @@ require-main-filename@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
|
||||
|
||||
requires-port@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||
|
||||
resolve-alpn@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.1.2.tgz#30b60cfbb0c0b8dc897940fe13fe255afcdd4d28"
|
||||
|
|
Loading…
Reference in New Issue
Block a user