mirror of
https://github.com/web3privacy/explorer-app.git
synced 2024-10-15 16:46:26 +02:00
feat(projects-grid): redesign projects grid
This commit is contained in:
parent
b6e1984046
commit
e699a2acfe
8 changed files with 244 additions and 337 deletions
|
@ -1,10 +1,12 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { ProjectShallow } from '~/types'
|
import type { ProjectShallow } from '~/types'
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
project: ProjectShallow
|
project: ProjectShallow
|
||||||
}>()
|
}>()
|
||||||
const { switcher } = storeToRefs(useData())
|
const { switcher } = storeToRefs(useData())
|
||||||
|
|
||||||
|
const projectItems = ['Swap,Mixer', { label: 'Openess', rating: props.project.ratings.openess, type: 'openess' }, { label: 'Technology', rating: props.project.ratings.technology, type: 'technology' }, { label: 'Privacy', rating: props.project.ratings.privacy, type: 'privacy' }, 'Ecosystem', 'Links']
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -18,230 +20,119 @@ const { switcher } = storeToRefs(useData())
|
||||||
transition-all
|
transition-all
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
relative
|
grid
|
||||||
max-w="96px lg:200px"
|
grid-cols="2 lg:10"
|
||||||
w-full
|
w-full
|
||||||
h="96px lg:200px"
|
|
||||||
:class="switcher ? '' : 'lg:max-w-full! lg:w-full '"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
col-span="1 lg:3"
|
||||||
flex
|
flex
|
||||||
items-center
|
items-center
|
||||||
justify-center
|
gap="12px lg:16px"
|
||||||
|
relative
|
||||||
w-full
|
w-full
|
||||||
my-auto
|
|
||||||
h-full
|
h-full
|
||||||
|
h="48px lg:64px"
|
||||||
|
:class="switcher ? '' : 'lg:max-w-full! lg:w-full '"
|
||||||
>
|
>
|
||||||
<NuxtImg
|
<NuxtImg
|
||||||
:src="project?.image || '/no-image-1-1.svg'"
|
:src="project?.image || '/no-image-1-1.svg'"
|
||||||
class="w-full h-auto"
|
class="w-full h-auto"
|
||||||
max-h="md:196px 96px"
|
max-h="md:64px 48px"
|
||||||
|
max-w="md:64px 48px"
|
||||||
self-center
|
self-center
|
||||||
z-10
|
z-10
|
||||||
object-fit
|
object-fit
|
||||||
bg="#121212"
|
bg="#121212"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<ClientOnly>
|
|
||||||
<Badge
|
|
||||||
v-if="project.percentage"
|
|
||||||
absolute
|
|
||||||
bottom-0.5
|
|
||||||
lg:bottom-0
|
|
||||||
right-0.5
|
|
||||||
lg:right-0
|
|
||||||
mr-2px
|
|
||||||
mb-2px
|
|
||||||
:text="`${project.percentage}%`"
|
|
||||||
class="leading-12px! text-12px! lg:text-18px! border-0!"
|
|
||||||
px="4px! lg:16px!"
|
|
||||||
py="4px! lg:8px!"
|
|
||||||
/>
|
|
||||||
</ClientOnly>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
h="96px lg:200px"
|
|
||||||
lg:py-24px
|
|
||||||
lg:pr-24px
|
|
||||||
flex
|
|
||||||
flex-col
|
|
||||||
justify-center
|
|
||||||
lg:justify-between
|
|
||||||
lg:gap-24px
|
|
||||||
w-full
|
|
||||||
text-white
|
|
||||||
:class="switcher ? '' : 'lg:p-16px! lg:py-16px!'"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
w-full
|
|
||||||
h-fit
|
|
||||||
flex
|
|
||||||
flex-col
|
|
||||||
gap-8px
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
w-fit
|
flex
|
||||||
|
flex-col
|
||||||
|
gap-y-4px
|
||||||
|
lg:flex-row
|
||||||
|
justify-center
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
w-fit
|
||||||
|
flex
|
||||||
|
items-center
|
||||||
|
gap-8px
|
||||||
|
@click.prevent="navigateTo(project.website, { external: true, open: { target: '_blank' } })"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
text="14px app-white"
|
||||||
|
font-700
|
||||||
|
line-clamp-1
|
||||||
|
hover:underline
|
||||||
|
underline-offset-3
|
||||||
|
leading="20px lg:32px"
|
||||||
|
>
|
||||||
|
{{ project.title1 }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
text-12px
|
||||||
|
leading-16px
|
||||||
|
lg:hidden
|
||||||
|
>
|
||||||
|
Usecases
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="(projectItem, index) of projectItems"
|
||||||
|
:key="projectItem.toString()"
|
||||||
|
hidden
|
||||||
|
lg:flex
|
||||||
|
items-center
|
||||||
|
justify-start
|
||||||
|
text-14px
|
||||||
|
leading-24px
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
v-if="typeof projectItem === 'string'"
|
||||||
|
text-app-text-grey
|
||||||
|
>
|
||||||
|
{{ projectItem }}
|
||||||
|
</p>
|
||||||
|
<ProjectRating
|
||||||
|
v-else
|
||||||
|
:score="index"
|
||||||
|
:rating="projectItem.rating"
|
||||||
|
:type="projectItem.type"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
flex
|
||||||
|
items-center
|
||||||
|
justify-end
|
||||||
|
w-full
|
||||||
|
gap-16px
|
||||||
|
>
|
||||||
|
<UnoIcon
|
||||||
|
block
|
||||||
|
lg:hidden
|
||||||
|
i-iconoir-internet
|
||||||
|
text="24px"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
flex
|
flex
|
||||||
items-center
|
items-center
|
||||||
gap-8px
|
justify-center
|
||||||
@click.prevent="navigateTo(project.website, { external: true, open: { target: '_blank' } })"
|
border="2px app-white"
|
||||||
>
|
text="14px md:18px"
|
||||||
<h1
|
leading="24px md:32px"
|
||||||
text="18px lg:24px app-white"
|
max-h-="28px md:32px"
|
||||||
font-700
|
max-w="48px md:56px"
|
||||||
line-clamp-1
|
|
||||||
hover:underline
|
|
||||||
underline-offset-3
|
|
||||||
>
|
|
||||||
{{ project.title1 }}
|
|
||||||
</h1>
|
|
||||||
<UnoIcon
|
|
||||||
i-web-open
|
|
||||||
text-16px
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<h2
|
|
||||||
text="14px app-text-grey"
|
|
||||||
overflow-hidden
|
|
||||||
text-ellipsis
|
|
||||||
line-clamp-2
|
|
||||||
lg:line-clamp-2
|
|
||||||
>
|
|
||||||
{{ project.description }}
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
w-full
|
|
||||||
flex
|
|
||||||
justify-between
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
w-full
|
w-full
|
||||||
max-w-692px
|
font-700
|
||||||
grid
|
|
||||||
whitespace-nowrap
|
whitespace-nowrap
|
||||||
:class="switcher ? 'grid-cols-5' : 'grid-cols-3'"
|
|
||||||
gap-24px
|
|
||||||
lg:grid
|
|
||||||
hidden
|
|
||||||
>
|
>
|
||||||
<ProjectInfoItem
|
{{ project.percentage }} %
|
||||||
:check-undefined="project?.github"
|
|
||||||
:link="project?.github"
|
|
||||||
title="Github"
|
|
||||||
bold
|
|
||||||
text-size="18px"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
flex
|
|
||||||
items-center
|
|
||||||
gap-8px
|
|
||||||
>
|
|
||||||
<UnoIcon
|
|
||||||
i-web-github
|
|
||||||
text-16px
|
|
||||||
/>
|
|
||||||
<span>{{ project?.github ? 'YES' : 'NO' }}</span>
|
|
||||||
</div>
|
|
||||||
</ProjectInfoItem>
|
|
||||||
<ProjectInfoItem
|
|
||||||
:check-undefined="project.readyness"
|
|
||||||
title="Readyness"
|
|
||||||
text-size="18px"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
flex
|
|
||||||
items-center
|
|
||||||
gap-12px
|
|
||||||
>
|
|
||||||
<UnoIcon
|
|
||||||
i-web-live
|
|
||||||
text-10px
|
|
||||||
:class="(project.readyness === 'Mainnet') ? 'color-#18FF2F' : (project.readyness === 'Testnet') ? 'color-#FFA800' : (project.readyness === 'Alpha') ? 'color-#FF0000' : ''"
|
|
||||||
/>
|
|
||||||
<span :class="(project.readyness === 'Alpha') ? 'color-#FFA800' : 'color-white'">{{ project.readyness }}</span>
|
|
||||||
</div>
|
|
||||||
</ProjectInfoItem>
|
|
||||||
<ProjectInfoItem
|
|
||||||
:check-undefined="true"
|
|
||||||
title="Team"
|
|
||||||
text-size="18px"
|
|
||||||
>
|
|
||||||
<span v-if="project.team?.length">{{ `${project.team?.length} members` }}</span>
|
|
||||||
<span
|
|
||||||
v-else
|
|
||||||
color="#FF0000"
|
|
||||||
>{{ 'Anonymous' }}</span>
|
|
||||||
</ProjectInfoItem>
|
|
||||||
<ProjectInfoItem
|
|
||||||
:check-undefined="project?.docs"
|
|
||||||
:link="project?.docs"
|
|
||||||
:color="project?.docs ? '#18FF2F' : '#FF0000'"
|
|
||||||
title="Docs"
|
|
||||||
bold
|
|
||||||
text-size="18px"
|
|
||||||
>
|
|
||||||
{{ project?.docs ? 'YES' : 'NO' }}
|
|
||||||
</ProjectInfoItem>
|
|
||||||
<ProjectInfoItem
|
|
||||||
:check-undefined="project.audits"
|
|
||||||
:link="project?.audits?.[0]?.link ?? undefined"
|
|
||||||
:color="project?.audits ? '#18FF2F' : '#FF0000'"
|
|
||||||
title="Audit"
|
|
||||||
bold
|
|
||||||
text-size="18px"
|
|
||||||
>
|
|
||||||
{{ project.audits ? 'YES' : 'NO' }}
|
|
||||||
</ProjectInfoItem>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
hidden
|
|
||||||
lg:flex
|
|
||||||
items-center
|
|
||||||
gap-16px
|
|
||||||
>
|
|
||||||
<UnoIcon
|
|
||||||
v-if="project.forum"
|
|
||||||
i-web-forum
|
|
||||||
text-28px
|
|
||||||
opacity-50
|
|
||||||
hover:opacity-100
|
|
||||||
@click.prevent="navigateTo(project.forum, { external: true, open: { target: '_blank' } })"
|
|
||||||
/>
|
|
||||||
<UnoIcon
|
|
||||||
v-if="project.explorer"
|
|
||||||
i-web-explorer
|
|
||||||
text-32px
|
|
||||||
opacity-50
|
|
||||||
hover:opacity-100
|
|
||||||
@click.prevent="navigateTo(project.explorer, { external: true, open: { target: '_blank' } })"
|
|
||||||
/>
|
|
||||||
<UnoIcon
|
|
||||||
v-if="project.twitter"
|
|
||||||
i-web-twitter_x
|
|
||||||
text-22px
|
|
||||||
opacity-50
|
|
||||||
hover:opacity-100
|
|
||||||
@click.prevent="navigateTo(project.twitter, { external: true, open: { target: '_blank' } })"
|
|
||||||
/>
|
|
||||||
<UnoIcon
|
|
||||||
v-if="project.coingecko"
|
|
||||||
i-web-coingecko
|
|
||||||
text-24px
|
|
||||||
opacity-50
|
|
||||||
hover:opacity-100
|
|
||||||
@click.prevent="navigateTo(project.coingecko, { external: true, open: { target: '_blank' } })"
|
|
||||||
/>
|
|
||||||
<UnoIcon
|
|
||||||
v-if="project.newsletter"
|
|
||||||
i-web-news
|
|
||||||
text-28px
|
|
||||||
opacity-50
|
|
||||||
hover:opacity-100
|
|
||||||
@click.prevent="navigateTo(project.newsletter, { external: true, open: { target: '_blank' } })"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -34,7 +34,7 @@ function onOptionSelected(value: string) {
|
||||||
>({{ isOptionSelected?.count }})</span></span>
|
>({{ isOptionSelected?.count }})</span></span>
|
||||||
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
||||||
<UnoIcon
|
<UnoIcon
|
||||||
i-heroicons-solid-chevron-down
|
i-ic-baseline-arrow-drop-down
|
||||||
text-app-black
|
text-app-black
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -13,6 +13,7 @@ defineProps<{
|
||||||
>
|
>
|
||||||
<UnoIcon
|
<UnoIcon
|
||||||
i-heroicons-solid-pencil
|
i-heroicons-solid-pencil
|
||||||
|
text-app-text-grey
|
||||||
text-24px
|
text-24px
|
||||||
/>
|
/>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import type { ProjectShallow } from '~/types'
|
import type { ProjectShallow } from '~/types'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
projects: ProjectShallow[]
|
projects: { title: string, projects: ProjectShallow[] }[]
|
||||||
}>()
|
}>()
|
||||||
const { switcher } = storeToRefs(useData())
|
const { switcher } = storeToRefs(useData())
|
||||||
|
|
||||||
|
@ -29,77 +29,102 @@ const cardTitles = ref< { label: string, togglable?: boolean, toggled?: boolean
|
||||||
flex-col
|
flex-col
|
||||||
items-start
|
items-start
|
||||||
>
|
>
|
||||||
<div
|
<template
|
||||||
v-if="displayedProjects.length"
|
v-for="group in projects"
|
||||||
flex
|
:key="group.title"
|
||||||
items-center
|
|
||||||
gap-x-12px
|
|
||||||
w-full
|
|
||||||
mb="8px md:16px"
|
|
||||||
>
|
|
||||||
<h2
|
|
||||||
text="app-white 16px md:24px"
|
|
||||||
font-700
|
|
||||||
leading="24px md:32px"
|
|
||||||
whitespace-nowrap
|
|
||||||
>
|
|
||||||
24 Defi
|
|
||||||
</h2>
|
|
||||||
<div
|
|
||||||
h-2px
|
|
||||||
w-full
|
|
||||||
bg-app-white
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
i-heroicons-solid-chevron-down
|
|
||||||
text="app-white 24px"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="displayedProjects.length"
|
|
||||||
flex
|
|
||||||
items-center
|
|
||||||
justify-between
|
|
||||||
w-full
|
|
||||||
mb-16px
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
||||||
flex
|
flex
|
||||||
items-center
|
items-center
|
||||||
gap-4px
|
gap-x-12px
|
||||||
|
w-full
|
||||||
|
mb="8px lg:16px"
|
||||||
|
mt-22px
|
||||||
>
|
>
|
||||||
<p
|
<h2
|
||||||
text="12px md:14px"
|
text="app-white 16px lg:24px"
|
||||||
leading="16px md:24px"
|
font-700
|
||||||
|
leading="24px lg:32px"
|
||||||
whitespace-nowrap
|
whitespace-nowrap
|
||||||
>
|
>
|
||||||
Project name
|
{{ group.projects.length }} {{ group.title }}
|
||||||
</p>
|
</h2>
|
||||||
|
<div
|
||||||
|
h-2px
|
||||||
|
w-full
|
||||||
|
bg-app-text-grey
|
||||||
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
i-heroicons-solid-chevron-down
|
i-ic-baseline-arrow-drop-down
|
||||||
text="app-white 20px"
|
text="app-text-grey 24px"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
hidden
|
grid
|
||||||
md:flex
|
grid-cols="2 lg:10"
|
||||||
items-center
|
|
||||||
justify-end
|
|
||||||
gap-48px
|
|
||||||
w-full
|
w-full
|
||||||
|
mb-16px
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="title in cardTitles"
|
|
||||||
:key="title.label"
|
|
||||||
flex
|
flex
|
||||||
items-center
|
items-center
|
||||||
gap-4px
|
gap-4px
|
||||||
|
col-span="1 lg:3"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
text="12px md:14px"
|
text="12px lg:14px app-text-grey"
|
||||||
leading="16px md:24px"
|
leading="16px lg:24px"
|
||||||
|
whitespace-nowrap
|
||||||
|
>
|
||||||
|
Project name
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
i-ic-baseline-arrow-drop-down
|
||||||
|
text="app-text-grey 20px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
flex
|
||||||
|
items-center
|
||||||
|
justify-end
|
||||||
|
gap-4px
|
||||||
|
lg:hidden
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
text="12px lg:14px app-text-grey"
|
||||||
|
leading="16px lg:24px"
|
||||||
|
>
|
||||||
|
Sort by:
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
text="12px lg:14px"
|
||||||
|
leading="16px lg:24px"
|
||||||
|
font-700
|
||||||
|
>
|
||||||
|
Score
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
i-ic-baseline-arrow-drop-down
|
||||||
|
text="app-text-grey 20px"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="title in cardTitles"
|
||||||
|
:key="title.label"
|
||||||
|
lg:flex
|
||||||
|
items-center
|
||||||
|
justify-start
|
||||||
|
last:justify-end
|
||||||
|
gap-4px
|
||||||
|
hidden
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
text="12px lg:14px app-text-grey"
|
||||||
|
leading="16px lg:24px"
|
||||||
whitespace-nowrap
|
whitespace-nowrap
|
||||||
>
|
>
|
||||||
{{ title.label }}
|
{{ title.label }}
|
||||||
|
@ -108,69 +133,44 @@ const cardTitles = ref< { label: string, togglable?: boolean, toggled?: boolean
|
||||||
v-if="title.togglable"
|
v-if="title.togglable"
|
||||||
type="button"
|
type="button"
|
||||||
:class="[title.toggled
|
:class="[title.toggled
|
||||||
? 'i-heroicons-solid-chevron-up'
|
? 'i-ic-baseline-arrow-drop-up'
|
||||||
: 'i-heroicons-solid-chevron-down']"
|
: 'i-ic-baseline-arrow-drop-down']"
|
||||||
text="app-white 20px"
|
text="app-text-grey 20px"
|
||||||
@click="title.toggled = !title.toggled"
|
@click="title.toggled = !title.toggled"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
flex
|
v-if="displayedProjects.length"
|
||||||
items-center
|
grid
|
||||||
gap-4px
|
:class="switcher ? 'grid-cols-1 lg:grid-cols-1' : 'xl:grid-cols-3 lg:grid-cols-3 sm:grid-cols-2 grid-cols-1'"
|
||||||
md:hidden
|
gap-16px
|
||||||
|
text-white
|
||||||
|
w-full
|
||||||
>
|
>
|
||||||
<p
|
<NewCard
|
||||||
text="12px md:14px"
|
v-for="project in group.projects"
|
||||||
leading="16px md:24px"
|
:key="project.id"
|
||||||
>
|
:project="project"
|
||||||
Sort by:
|
|
||||||
</p>
|
|
||||||
<p
|
|
||||||
text="12px md:14px"
|
|
||||||
leading="16px md:24px"
|
|
||||||
font-700
|
|
||||||
>
|
|
||||||
Score
|
|
||||||
</p>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
i-heroicons-solid-chevron-down
|
|
||||||
text="app-white 20px"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div v-else>
|
||||||
<div
|
<h3>No Projects found...</h3>
|
||||||
v-if="displayedProjects.length"
|
</div>
|
||||||
grid
|
<button
|
||||||
:class="switcher ? 'grid-cols-1 lg:grid-cols-1' : 'xl:grid-cols-3 lg:grid-cols-3 sm:grid-cols-2 grid-cols-1'"
|
v-if="displayedProjects.length < projects.length"
|
||||||
gap-16px
|
mt-29px
|
||||||
text-white
|
text="14px"
|
||||||
w-full
|
leading-24px
|
||||||
>
|
font-700
|
||||||
<Card
|
px-12px
|
||||||
v-for="project in displayedProjects"
|
py-4px
|
||||||
:key="project.id"
|
border-2px
|
||||||
:project="project"
|
border-app-white
|
||||||
/>
|
@click="showMoreProjects"
|
||||||
</div>
|
>
|
||||||
<div v-else>
|
Load more projects
|
||||||
<h3>No Projects found...</h3>
|
</button>
|
||||||
</div>
|
</template>
|
||||||
<button
|
|
||||||
v-if="displayedProjects.length < projects.length"
|
|
||||||
mt-29px
|
|
||||||
text="14px"
|
|
||||||
leading-24px
|
|
||||||
font-700
|
|
||||||
px-12px
|
|
||||||
py-4px
|
|
||||||
border-2px
|
|
||||||
border-app-white
|
|
||||||
@click="showMoreProjects"
|
|
||||||
>
|
|
||||||
Load more projects
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -33,7 +33,7 @@ const selectedValue = useVModel(props, 'modelValue', emits)
|
||||||
<span class="block truncate mr-8px">{{ props.options.find(option => option.value === selectedValue)?.label }}</span>
|
<span class="block truncate mr-8px">{{ props.options.find(option => option.value === selectedValue)?.label }}</span>
|
||||||
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
||||||
<UnoIcon
|
<UnoIcon
|
||||||
i-heroicons-solid-chevron-down
|
i-ic-baseline-arrow-drop-down
|
||||||
:class="[blackAndWhite ? ' text-app-white' : 'text-app-black']"
|
:class="[blackAndWhite ? ' text-app-white' : 'text-app-black']"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,27 +1,26 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { InputOption } from '~/types'
|
import type { InputOption } from '~/types'
|
||||||
|
|
||||||
const { categories, filteredProjectsCount, selectedCategoryId } = storeToRefs(useData())
|
const { categories, usecases, ecosystems, assets, features, filteredProjectsCount, selectedCategoryId } = storeToRefs(useData())
|
||||||
|
|
||||||
const selectedUsecaseId = ref('usecase')
|
const selectedUsecaseId = ref('all')
|
||||||
const selectedEcosystemId = ref('ecosystem')
|
const selectedEcosystemId = ref('all')
|
||||||
const selectedAssetsUsedId = ref('assetsUsed')
|
const selectedAssetsUsedId = ref('all')
|
||||||
const selectedFeaturesId = ref('features')
|
const selectedFeaturesId = ref('all')
|
||||||
|
|
||||||
const categoriesOptions = ref(categories.value ? categories.value.map(c => ({ label: c.name, value: c.id, count: c.projectsCount })) : [])
|
const categoryOptions = ref<InputOption>(categories.value ? [{ label: 'Category', value: 'all' }, ...categories.value.map(c => ({ label: c.name, value: c.id, count: c.projectsCount }))] : [])
|
||||||
const extendedOptions: InputOption[] = [
|
const usecaseOptions = ref<InputOption>(usecases.value ? [{ label: 'Usecase', value: 'all' }, ...usecases.value.map(u => ({ label: u.name, value: u.id }))] : [])
|
||||||
{ label: 'Category', value: 'all' },
|
const ecosystemOptions = ref<InputOption>(ecosystems.value ? [{ label: 'Ecosystem', value: 'all' }, ...ecosystems.value.map(e => ({ label: e.name, value: e.id }))] : [])
|
||||||
...categoriesOptions.value,
|
const assetOptions = ref<InputOption>(assets.value ? [{ label: 'Asset used', value: 'all' }, ...assets.value.map(a => ({ label: a.name, value: a.id }))] : [])
|
||||||
]
|
const featureOptions = ref<InputOption>(features.value ? [{ label: 'Feature', value: 'all' }, ...features.value.map(f => ({ label: f.name, value: f.id }))] : [])
|
||||||
|
// const selectedCategory = computed(() => {
|
||||||
|
// return categories.value.find(c => c.id === selectedCategoryId.value)
|
||||||
|
// })
|
||||||
|
|
||||||
const selectedCategory = computed(() => {
|
// const sortedFilteredCategories = computed(() => ([
|
||||||
return categories.value.find(c => c.id === selectedCategoryId.value)
|
// categories.value.find(c => c.id === 'defi')!,
|
||||||
})
|
// ...[...categories.value].sort((a, b) => a.name.localeCompare(b.name)).filter(c => c.id !== 'defi'),
|
||||||
|
// ]))
|
||||||
const sortedFilteredCategories = computed(() => ([
|
|
||||||
categories.value.find(c => c.id === 'defi')!,
|
|
||||||
...[...categories.value].sort((a, b) => a.name.localeCompare(b.name)).filter(c => c.id !== 'defi'),
|
|
||||||
]))
|
|
||||||
|
|
||||||
const { showBar } = storeToRefs(useNavigaiton())
|
const { showBar } = storeToRefs(useNavigaiton())
|
||||||
const swipeEl = ref()
|
const swipeEl = ref()
|
||||||
|
@ -78,6 +77,7 @@ watch([scrollY, top, y], (newValues, oldValues) => {
|
||||||
>
|
>
|
||||||
<SearchBox
|
<SearchBox
|
||||||
flex-1
|
flex-1
|
||||||
|
placeholder:text-app-text-grey
|
||||||
:placeholder="`Search in ${filteredProjectsCount} Projects`"
|
:placeholder="`Search in ${filteredProjectsCount} Projects`"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
|
@ -85,32 +85,40 @@ watch([scrollY, top, y], (newValues, oldValues) => {
|
||||||
flex
|
flex
|
||||||
items-center
|
items-center
|
||||||
gap-16px
|
gap-16px
|
||||||
overflow-x-auto
|
|
||||||
>
|
>
|
||||||
<CategorySelectBox
|
<CategorySelectBox
|
||||||
v-model="selectedCategoryId"
|
v-model="selectedCategoryId"
|
||||||
:options="extendedOptions"
|
:options="categoryOptions"
|
||||||
|
name="categorySelect"
|
||||||
w-full
|
w-full
|
||||||
@selected="selectedCategoryId === 'all' ? navigateTo(`/`) : navigateTo(`/category/${selectedCategoryId}`)"
|
@selected="selectedCategoryId === 'all' ? navigateTo(`/`) : navigateTo(`/category/${selectedCategoryId}`)"
|
||||||
/>
|
/>
|
||||||
<CategorySelectBox
|
<CategorySelectBox
|
||||||
|
v-if="usecases.length"
|
||||||
v-model="selectedUsecaseId"
|
v-model="selectedUsecaseId"
|
||||||
:options="[{ label: 'Usecase', value: 'usecase' }]"
|
name="usecaseSelect"
|
||||||
|
:options="usecaseOptions"
|
||||||
w-full
|
w-full
|
||||||
/>
|
/>
|
||||||
<CategorySelectBox
|
<CategorySelectBox
|
||||||
|
v-if="ecosystems.length"
|
||||||
v-model="selectedEcosystemId"
|
v-model="selectedEcosystemId"
|
||||||
:options="[{ label: 'Ecosystem', value: 'ecosystem' }]"
|
name="ecosystemSelect"
|
||||||
|
:options="ecosystemOptions"
|
||||||
w-full
|
w-full
|
||||||
/>
|
/>
|
||||||
<CategorySelectBox
|
<CategorySelectBox
|
||||||
|
v-if="assets.length"
|
||||||
v-model="selectedAssetsUsedId"
|
v-model="selectedAssetsUsedId"
|
||||||
:options="[{ label: 'Assets used', value: 'assetsUsed' }]"
|
name="assetsUsedSelect"
|
||||||
|
:options="assetOptions"
|
||||||
w-full
|
w-full
|
||||||
/>
|
/>
|
||||||
<CategorySelectBox
|
<CategorySelectBox
|
||||||
|
v-if="features.length"
|
||||||
v-model="selectedFeaturesId"
|
v-model="selectedFeaturesId"
|
||||||
:options="[{ label: 'Features', value: 'features' }]"
|
name="featuresSelect"
|
||||||
|
:options="featureOptions"
|
||||||
w-full
|
w-full
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,9 +7,11 @@ useSeoMeta({
|
||||||
ogDescription: 'There are challenges in finding crucial technical details and comparing various privacy-focused projects.',
|
ogDescription: 'There are challenges in finding crucial technical details and comparing various privacy-focused projects.',
|
||||||
ogImage: '/web3privacy_eye.webp',
|
ogImage: '/web3privacy_eye.webp',
|
||||||
})
|
})
|
||||||
const { filteredProjects } = storeToRefs(useData())
|
const { groupedProjectsPerCategory } = storeToRefs(useData())
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ProjectGrid :projects="filteredProjects" />
|
<div>
|
||||||
|
<ProjectGrid :projects="groupedProjectsPerCategory" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
5
utils/text.ts
Normal file
5
utils/text.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import moment from 'moment'
|
||||||
|
|
||||||
|
export function formatDate(date: Date | string) {
|
||||||
|
return moment(date).format('MM / YYYY')
|
||||||
|
}
|
Loading…
Reference in a new issue