Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 30 additions & 13 deletions app.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
<template>
<div class="grid grid-rows-[max-content_1fr_max-content] grid-cols-[1fr] w-full justify-items-center">
<div
class="grid grid-rows-[max-content_1fr_max-content] grid-cols-[1fr] w-full justify-items-center"
>
<div class="max-w-[1300px] w-full lg:px-md">
<SvgIcon name="logo" class="w-[170px] mt-md" />
</div>
<div class="max-w-[1100px] w-full grid gap-2xl">
<div class="grid gap-lg grid-cols-2 grid-rows-1 sm:grid-cols-1 mt-3xl items-center">
<div class="h-max lg:px-md">
<h1 class="font-title text-5xl text-white-50 font-bold">Race to stake</h1>
<p class="text-xl text-white-200 mt-sm">
Secure the network, earn rewards
</p>
<div
class="grid gap-lg grid-cols-2 grid-rows-1 sm:grid-cols-1 mt-3xl items-center"
>
<div class="h-max lg:px-md">
<h1 class="font-title text-5xl text-white-50 font-bold">
Race to stake
</h1>
<p class="text-xl text-white-200 mt-sm">
Secure the network, earn rewards
</p>
</div>
<APYCalculator :total-staked="totalStaked" />
</div>
<StakeVolume
:visible-stakers="visibleStakers"
:total-staked="totalStaked"
:loading="loading"
class="h-max md:m-md"
/>
<div class="md:m-md">
<LeaderBoard :visible-stakers="visibleStakers" class="h-max" />
</div>
<APYCalculator />
</div>
<StakeVolume :visible-stakers="visibleStakers" :loading="loading" class="h-max md:m-md" />
<div class="md:m-md">
<LeaderBoard :visible-stakers="visibleStakers" class="h-max" />
</div>
</div>
<WFooter class="!bg-black-800 mt-2xl" :footer-sections="footerSections" />
</div>
Expand Down Expand Up @@ -61,6 +72,12 @@ const visibleStakers = computed(() => {
})
})

const totalStaked = computed(() => {
return visibleStakers.value
? visibleStakers.value.reduce((acc, staker) => acc + staker.amount, 0)
: 0
})

// const visibleStakers = ref(mockStakers);
const loading = ref(false)

Expand Down
3 changes: 1 addition & 2 deletions assets/styles/tailwind.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

@import url("wit-vue-ui/style.css");
html {
@apply bg-black-950;
}
}
77 changes: 39 additions & 38 deletions components/APYCalculator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
</h2>
<p class="text-white-200">Calculate your potential earnings</p>

<div class="grid grid-cols-[1fr_max-content] sm:grid-cols-1 gap-md sm:gap-sm justify-center items-end">
<div
class="grid grid-cols-[1fr_max-content] sm:grid-cols-1 gap-md sm:gap-sm justify-center items-end"
>
<div class="mt-md">
<label
class="block text-xs font-bold text-[rgb(0,226,237)] mb-sm"
>
<label class="block text-xs font-bold text-[rgb(0,226,237)] mb-sm">
Enter an Amount
</label>
<input
Expand All @@ -25,64 +25,65 @@
>
Calculate APY
</button>
<p
v-if="showError"
class="text-red-50 text-sm"
>
{{ errorMessage }}
<p v-if="showError" class="text-red-50 text-sm">
{{ errorMessage }}
</p>
</div>

<div
v-if="calculatedAPY && !errorMessage"
class="mt-md p-6 rounded-lg"
>
<div class="flex sm:flex-col gap-md">
<div class="grid justify-center items-middle text-center p-md bg-black-950 rounded-lg w-full">
<p class="text-sm text-white-200 mb-xs">
Annual Percentage Yield
</p>
<p class="text-2xl font-bold text-wit-blue-500">
{{ calculatedAPY }}%
</p>
</div>
<div class="grid justify-center items-middle text-center p-md bg-black-950 rounded-lg w-full">
<p class="text-sm text-white-200 mb-xs">Monthly Rewards</p>
<p class="text-2xl font-bold text-wit-blue-500 w-max">
{{ estimatedMonthlyRewards }} $WIT
</p>
</div>
<div v-if="calculatedAPY && !errorMessage" class="mt-md p-6 rounded-lg">
<div class="flex sm:flex-col gap-md">
<div
class="grid justify-center items-middle text-center p-md bg-black-950 rounded-lg w-full"
>
<p class="text-sm text-white-200 mb-xs">Annual Percentage Yield</p>
<p class="text-2xl font-bold text-wit-blue-500">
{{ calculatedAPY }}%
</p>
</div>
<div
class="grid justify-center items-middle text-center p-md bg-black-950 rounded-lg w-full"
>
<p class="text-sm text-white-200 mb-xs">Monthly Rewards</p>
<p class="text-2xl font-bold text-wit-blue-500 w-max">
{{ estimatedMonthlyRewards }} $WIT
</p>
</div>
</div>
</BaseCard>
</div>
</BaseCard>
</template>

<script setup>
import { formatNumber } from "@/utils/formatNumber.js"
import { ref } from "vue"

const props = defineProps({
totalStaked: Number,
})

const calculatedAPY = ref(null)
const estimatedMonthlyRewards = ref(null)
const calculatorInput = ref("")
const errorMessage = ref("")
const calculateAPY = () => {
if (!Number(calculatorInput.value)) {
errorMessage.value = "Please enter a valid number"
return
errorMessage.value = "Please enter a valid number"
return
} else if (Number(calculatorInput.value) < 10_000) {
errorMessage.value = "Minimum skate amount is 10,000 $WIT"
return
} else if (Number(calculatorInput.value) > 10_000_000) {
} else if (Number(calculatorInput.value) > 10_000_000) {
errorMessage.value = "Maximum skate amount is 10,000,000 $WIT"
return
} else {
errorMessage.value = ""
// const yearlyEmission = 78_840_000
// const initial = 300_000_000
const apy = 0.2628 // yearlyEmission / initial
calculatedAPY.value = "26.28"
const yearlyEmission = 78_840_000_000_000_000
const apy = yearlyEmission / props.totalStaked
calculatedAPY.value = (apy * 100).toFixed(2)
const amount = parseFloat(calculatorInput.value) || 100000
estimatedMonthlyRewards.value = formatNumber(Math.floor((amount * apy) / 12))
estimatedMonthlyRewards.value = formatNumber(
Math.floor((amount * apy) / 12),
)
}
}
</script>
</script>
2 changes: 1 addition & 1 deletion components/BaseCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
<div class="bg-black-800 rounded-3xl">
<slot></slot>
</div>
</template>
</template>
119 changes: 58 additions & 61 deletions components/LeaderBoard.vue
Original file line number Diff line number Diff line change
@@ -1,73 +1,70 @@
<template>
<BaseCard class="!w-full">
<h2 class="text-xl font-bold text-white-50 mb-md p-md sm:w-max">
Staking Leaderboard
</h2>
<table class="w-full divide-y divide-white-500 text-white-200 mb-md sm:w-md">
<thead class="text-xs text-white-200 sm:hidden">
<tr>
<th scope="col" class="px-md py-md text-start">
Rank
</th>
<th scope="col" class="px-md py-md text-start">
Address
</th>
<th scope="col" class="px-md py-md text-start">
Staked Amount
</th>
<th scope="col" class="px-md text-end">
Timestamp
</th>
</tr>
</thead>
<tbody>
<tr
v-for="(staker, index) in visibleStakers"
:key="staker.withdrawer"
class="transition-all duration-200 even:bg-black-600 sm:grid sm:grid-col-1 sm:py-md"
<BaseCard class="!w-full">
<h2 class="text-xl font-bold text-white-50 mb-md p-md sm:w-max">
Staking Leaderboard
</h2>
<table
class="w-full divide-y divide-white-500 text-white-200 mb-md sm:w-md"
>
<thead class="text-xs text-white-200 sm:hidden">
<tr>
<th scope="col" class="px-md py-md text-start">Rank</th>
<th scope="col" class="px-md py-md text-start">Address</th>
<th scope="col" class="px-md py-md text-start">Staked Amount</th>
<th scope="col" class="px-md text-end">Timestamp</th>
</tr>
</thead>
<tbody>
<tr
v-for="(staker, index) in visibleStakers"
:key="staker.withdrawer"
class="transition-all duration-200 even:bg-black-600 sm:grid sm:grid-col-1 sm:py-md"
>
<th class="label">Rank</th>
<td class="px-md py-md [&&]:sm:pt-sm whitespace-nowrap">
{{ index + 1 }}
</td>
<th class="label">Address</th>
<td
class="px-md py-md [&&]:sm:pt-sm whitespace-nowrap text-sm text-wit-blue-500 font-mono truncate hover:cursor-pointer [&&]sm:py-xs"
>
<th class="label">Rank</th>
<td class="px-md py-md [&&]:sm:pt-sm whitespace-nowrap">
{{ index + 1 }}
</td>
<th class="label">Address</th>
<td
class="px-md py-md [&&]:sm:pt-sm whitespace-nowrap text-sm text-wit-blue-500 font-mono truncate hover:cursor-pointer [&&]sm:py-xs"
<a
:href="`https://witnet.network/search/${staker.withdrawer}`"
target="_blank"
>
<a :href="`https://witnet.network/search/${staker.withdrawer}`" target="_blank">
{{ staker.withdrawer ?? "unknown" }}
</a>
</td>
<th class="label">Amount</th>
<td
class="px-md py-md [&&]:sm:pt-sm whitespace-nowrap text-sm font-bold text-black"
>
{{ formatNumber(nanoWitToWit(staker.amount).toFixed()) }} $WIT
</td>
<th class="label">Timestamp</th>
<td
class="px-md py-md [&&]:sm:pt-sm whitespace-nowrap text-sm text-end sm:text-start sm:py-sm font-mono"
>
{{ formatDate(staker.timestamp) }}
</td>
</tr>
</tbody>
</table>
<div v-if="loading" class="text-center py-4">
<div
class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-wit-blue-500"
/>
</div>
{{ staker.withdrawer ?? "unknown" }}
</a>
</td>
<th class="label">Amount</th>
<td
class="px-md py-md [&&]:sm:pt-sm whitespace-nowrap text-sm font-bold text-black"
>
{{ formatNumber(nanoWitToWit(staker.amount).toFixed()) }} $WIT
</td>
<th class="label">Timestamp</th>
<td
class="px-md py-md [&&]:sm:pt-sm whitespace-nowrap text-sm text-end sm:text-start sm:py-sm font-mono"
>
{{ formatDate(staker.timestamp) }}
</td>
</tr>
</tbody>
</table>
<div v-if="loading" class="text-center py-4">
<div
class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-wit-blue-500"
/>
</div>
<!-- <div class="border-t border-white-500 flex justify-end pb-md" v-if="total > pageSize">
<WPagination :total="total" :pageSize="pageSize" :page="currentPage" v-model:page="currentPage" class="text-white-50 mt-md" />
</div> -->
</BaseCard>
</BaseCard>
</template>

<script setup>
import dayjs from "dayjs"
// import { WPagination } from "wit-vue-ui"
import {ref, watch} from 'vue'
import { ref, watch } from "vue"
const props = defineProps({
loading: Boolean,
visibleStakers: Array,
Expand All @@ -82,7 +79,7 @@ const pageSize = ref(15)
const currentPage = ref(1)
const total = computed(() => props.visibleStakers.length)
watch(currentPage, (valX, _valY) => {
console.log('Page updated:', valX)
console.log("Page updated:", valX)
})
</script>
<style lang="scss" scoped>
Expand All @@ -95,4 +92,4 @@ watch(currentPage, (valX, _valY) => {
.t-value {
@apply px-md py-md [&&]:sm:pt-sm;
}
</style>
</style>
Loading
Loading