Skip to content

Commit

Permalink
Merge branch 'develop' into feature/happ-details
Browse files Browse the repository at this point in the history
  • Loading branch information
mateuszRybczonek committed Nov 3, 2023
2 parents b37fcd1 + 43bf467 commit 27c2609
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/assets/css/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
--black-color: #000000;

--primary-color: #00cad9;
--primary-light-color: rgba(176, 236, 240, 0.72);
--primary-light-color: rgba(0, 202, 217, 0.06);

--grey-color: #606c8b;
--grey-dark-color: #313c59;
Expand Down
121 changes: 121 additions & 0 deletions src/components/BaseTabSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<script setup lang="ts">
interface Tab {
value: string
name: string
current: boolean
}
const props = defineProps<{
tabs: Tab[]
}>()
const emit = defineEmits(['update'])
</script>

<template>
<div>
<div class="desktop-tab-select-wrapper">
<nav
class="desktop-tab-select"
aria-label="Tabs"
>
<span
v-for="(tab, tabIdx) in props.tabs"
:key="tab.name"
:class="[
tab.current ? 'desktop-tab-select__item--current' : 'desktop-tab-select__item--inactive',
tabIdx === 0 ? 'desktop-tab-select--rounded-l' : '',
tabIdx === tabs.length - 1 ? 'desktop-tab-select--rounded-r' : '',
'desktop-tab-select__item'
]"
:aria-current="tab.current ? 'page' : undefined"
@click="emit('update', tab.value)"
>
<span>{{ tab.name }}</span>
<span
aria-hidden="true"
:class="[
{ 'desktop-tab-select__item-label--current': tab.current },
'desktop-tab-select__item-label'
]"
/>
</span>
</nav>
</div>
</div>
</template>

<style lang="scss" scoped>
.desktop-tab-select-wrapper {
display: block;
}
.desktop-tab-select {
isolation: isolate;
border-right-width: 0;
border-left-width: 0;
border-color: rgb(229 231 235);
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
color: var(--grey-color);
&:hover {
cursor: pointer;
}
&__item {
position: relative;
min-width: 0;
flex: 1;
overflow: hidden;
background-color: white;
padding: 2px 14px;
text-align: center;
font-size: 12px;
font-weight: 800;
border: 1px solid var(--grey-light-color);
&--current {
color: var(--primary-color);
border-color: var(--primary-color);
background-color: var(--primary-light-color);
}
&--inactive {
&:hover {
color: var(--primary-color);
border-color: var(--primary-color);
}
}
&:focus {
z-index: 10;
}
&-label {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 2px;
&--current {
color: var(--primary-color);
}
}
}
&--rounded-l {
border-top-left-radius: 0.3rem;
border-bottom-left-radius: 0.3rem;
}
&--rounded-r {
border-top-right-radius: 0.3rem;
border-bottom-right-radius: 0.3rem;
}
&--current {
color: var(--grey-dark-color);
}
}
</style>
3 changes: 2 additions & 1 deletion src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ export default {
},
hosted_happs: {
hosted_for: 'Hosted for',
no_happs: 'You’re not hosting any hApps',
no_active_happs: 'You’re not hosting any hApps',
no_inactive_happs: 'You do not have any inactive hApps',
no_filtered_happs: 'No hApps match your search',
title: 'Top Hosted hApps'
},
Expand Down
83 changes: 61 additions & 22 deletions src/pages/HAppsPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import BaseSearchInput from '@uicommon/components/BaseSearchInput.vue'
import HAppCard from '@uicommon/components/HAppCard.vue'
import { EChipType } from '@uicommon/types/ui'
import { computed, onMounted, ref } from 'vue'
import BaseTabSelect from '@/components/BaseTabSelect.vue'
import SortByDropdown from '@/components/hApps/SortByDropdown.vue'
import PrimaryLayout from '@/components/PrimaryLayout.vue'
import { kSortOptions } from '@/constants/ui'
Expand All @@ -17,6 +18,22 @@ const store = useDashboardStore()
const isLoading = ref(false)
const isError = ref(false)
const selectedTab = ref('active')
const tabs = computed(() => [
{ value: 'active', name: 'Active hApps', current: selectedTab.value === 'active' },
{
value: 'inactive',
name: 'Inactive hApps',
href: '#',
current: selectedTab.value === 'inactive'
}
])
function onTabChange(value: string): void {
selectedTab.value = value
}
const filterValue = ref('')
const filterIsActive = ref(false)
Expand All @@ -30,30 +47,38 @@ function onFilterChange({ value, isActive }: FilterChangeProps): void {
filterValue.value = value
}
const happs = computed((): HApp[] | { error: unknown } => store.hostedHApps)
const sortBy = ref(kSortOptions.alphabetical.value)
const hostedHApps = computed((): HApp[] | { error: unknown } => store.hostedHApps)
const filteredHApps = computed((): HApp[] => {
let hAppsFilteredByActivity: HApp[] = []
const sortByLogic: (a: HApp, b: HApp) => number =
// Sorting by earnings is not available now as we don't have a property
// like that in the HApp, we use 'sourceChains' for now
sortBy.value === kSortOptions.earnings.value
? (a: HApp, b: HApp): number => (a.sourceChains < b.sourceChains ? 1 : -1)
: (a: HApp, b: HApp): number => (a.name > b.name ? 1 : -1)
if (isErrorPredicate(hostedHApps.value) && hostedHApps.value.error) {
// If no hosted hApps
if (isErrorPredicate(happs.value) && happs.value.error) {
return []
} else if (!isErrorPredicate(happs.value)) {
// If hApps are hosted filter them by activity
hAppsFilteredByActivity =
selectedTab.value === 'active'
? happs.value.filter((hApp: HApp) => hApp.enabled)
: happs.value.filter((hApp: HApp) => !hApp.enabled)
}
if (!isErrorPredicate(hostedHApps.value) && filterIsActive.value && filterValue.value) {
return hostedHApps.value
if (!isErrorPredicate(hAppsFilteredByActivity) && filterIsActive.value && filterValue.value) {
return hAppsFilteredByActivity
.filter((hApp: HApp) => hApp.name.toLowerCase().includes(filterValue.value.toLowerCase()))
.sort(sortByLogic)
}
if (!isErrorPredicate(hostedHApps.value)) {
return [...hostedHApps.value].sort(sortByLogic)
if (!isErrorPredicate(hAppsFilteredByActivity)) {
return [...hAppsFilteredByActivity].sort(sortByLogic)
}
return []
Expand All @@ -71,7 +96,7 @@ async function getData(): Promise<void> {
await store.getHostedHApps()
if (isErrorPredicate(hostedHApps.value) && hostedHApps.value.error) {
if (isErrorPredicate(happs.value) && happs.value.error) {
isError.value = true
}
Expand All @@ -96,19 +121,26 @@ onMounted(async () => {
@try-again-clicked="getData"
>
<div class="happs__controls">
<BaseSearchInput
:value="filterValue"
:is-disabled="isLoading"
label-translation-key="$.filter_by"
@update="onFilterChange"
<BaseTabSelect
:tabs="tabs"
@update="onTabChange"
/>

<SortByDropdown
:value="sortBy"
is-disabled
class="happs__sort-by-dropdown"
@update:value="onSortByChange"
/>
<div class="happs__controls--left">
<BaseSearchInput
:value="filterValue"
:is-disabled="isLoading"
label-translation-key="$.filter_by"
@update="onFilterChange"
/>

<SortByDropdown
:value="sortBy"
is-disabled
class="happs__sort-by-dropdown"
@update:value="onSortByChange"
/>
</div>
</div>

<div v-if="!isLoading && !isError">
Expand Down Expand Up @@ -140,7 +172,7 @@ onMounted(async () => {
>
<HAppCard
is-empty
:empty-card-label="filterValue ? 'hosted_happs.no_filtered_happs' : 'hosted_happs.no_happs'"
:empty-card-label="filterValue ? 'hosted_happs.no_filtered_happs' : selectedTab === 'active' ? 'hosted_happs.no_active_happs' : 'hosted_happs.no_inactive_happs'"
class="happs__happ-list-item"
/>
</div>
Expand All @@ -154,16 +186,23 @@ onMounted(async () => {
position: relative;
display: flex;
align-items: center;
justify-content: flex-end;
justify-content: space-between;
padding: 9px 0;
&--left {
position: relative;
display: flex;
align-items: center;
justify-content: flex-end;
padding: 9px 0;
}
}
&__happ-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(600px, 600px));
grid-template-rows: repeat(auto-fill, 180px);
grid-gap: 24px;
margin-top: 12px;
height: calc(100vh - 175px);
overflow-y: scroll;
}
Expand Down

0 comments on commit 27c2609

Please sign in to comment.