explorer-app/components/Project/ProjectHeading.vue

298 lines
6.8 KiB
Vue
Raw Normal View History

2023-12-19 18:43:42 +01:00
<script lang="ts" setup>
2024-07-22 12:17:18 +02:00
import type { Project, ProjectIndexable } from '~/types'
2023-12-19 18:43:42 +01:00
const props = defineProps<{
project: Project
}>()
const availableSupport = computed(() => {
const filteredKeys = ['forum', 'discord', 'twitter', 'lens', 'farcaster', 'telegram']
if (typeof props.project.links === 'object' && (props.project.links !== null || props.project.links !== undefined))
return Object.keys(props.project.links).filter(key => filteredKeys.includes(key)).length
return 0
})
/**
* From data points
- product readiness
- docs (yes/no)
- github (yes/no)
- team: anon / public
- audit: yes / no
*/
2024-07-22 12:17:18 +02:00
const calculateScore = computed(() => {
const criterias: { value: keyof ProjectIndexable, key: keyof ProjectIndexable | '' }[] = [
2024-07-22 12:17:18 +02:00
{ value: 'product_readiness', key: '' },
2024-07-22 09:36:53 +02:00
{ value: 'github', key: 'links' },
{ value: 'docs', key: 'links' },
2024-07-22 12:17:18 +02:00
{ value: 'team', key: '' },
{ value: 'audits', key: '' },
2024-07-22 09:36:53 +02:00
]
2024-07-22 09:36:53 +02:00
let matched = 0
for (let i = 0; i < criterias.length; i++) {
2024-07-22 09:36:53 +02:00
let value
2024-07-22 12:17:18 +02:00
// value = ((criterias[i].key ?? props.project[criterias[i].value as keyof typeof props.project]) ?? null === null) ? null : (props.project as ProjectIndexable)[criterias[i].key][criterias[i].value]
const indexableProject = props.project as ProjectIndexable
2024-07-22 12:17:18 +02:00
if (criterias[i].key !== '')
value = (indexableProject[criterias[i].key] as any)?.[criterias[i].value]
2024-07-22 12:17:18 +02:00
else
value = indexableProject?.[criterias[i].value]
// console.log(props.project?.links?.github);
// console.log(Object.keys(props.indexableProject["team"]).length);
if (value === null || value === undefined)
continue
2024-07-22 09:36:53 +02:00
if (fulfilled(value))
matched++
}
2024-07-22 09:36:53 +02:00
return 100 / criterias.length * matched
})
function fulfilled(value: any): boolean {
2024-07-22 09:36:53 +02:00
const type = typeof value
switch (type) {
case 'string':
2024-07-22 09:36:53 +02:00
if (value !== '')
return true
break
case 'object':
if (Object.keys(value!).length > 0)
2024-07-22 09:36:53 +02:00
return true
break
default:
2024-07-22 09:36:53 +02:00
return false
}
2024-07-22 12:17:18 +02:00
return false
}
2023-12-19 18:43:42 +01:00
const logo = props.project?.logos?.at(0)?.url
</script>
<template>
<div
2024-09-12 08:41:48 +02:00
flex
flex-col
gap-y-16px
lg:flex-row
items-center
lg:gap-32px
>
2024-07-22 09:36:53 +02:00
<NuxtImg
2024-09-12 08:41:48 +02:00
max-w-200px
max-h-200px
shrink
2024-09-12 08:41:48 +02:00
border="1px app-text-grey"
:src="logo ?? '/no-image-1-1.svg'"
2024-09-12 08:41:48 +02:00
class="bg-app-bg-grey object-cover h-full vertical-align[middle] block w-full h-[300px]"
2024-07-22 09:36:53 +02:00
/>
2024-09-12 08:41:48 +02:00
<div
grow
w-full
>
<div
flex
flex-col
2024-09-12 08:41:48 +02:00
items-center
lg:items-start
justify-between
2024-09-12 08:41:48 +02:00
gap-y="lg:12px 24px"
text-app-text-grey
w-full
>
2024-09-12 08:41:48 +02:00
<div mt-4px>
2024-07-22 09:36:53 +02:00
<NuxtLink
:to="project.links?.web"
target="_blank"
flex
items-center
gap-12px
hover:underline
2024-07-22 09:36:53 +02:00
underline-offset-3
>
<h1
text="24px sm:32px app-white"
leading-32px
font-700
>
2023-12-19 18:43:42 +01:00
{{ project.name }}
</h1>
<UnoIcon
2024-09-12 08:41:48 +02:00
i-ic-twotone-open-in-new
text="22px app-white"
/>
2023-12-19 18:43:42 +01:00
</NuxtLink>
</div>
2024-07-22 09:36:53 +02:00
<div
flex
justify-center
2024-09-12 08:41:48 +02:00
lg:grid
grid-cols-10
w-full
items-center
mt-4px
2024-07-22 09:36:53 +02:00
>
2024-09-12 08:41:48 +02:00
<h2
hidden
lg:block
>
Usecases:
</h2>
<p
text-app-white
col-span-9
>
Swap, Mixer
</p>
2023-12-19 18:43:42 +01:00
</div>
2024-09-12 08:41:48 +02:00
<div
grid
grid-cols-2
gap-y-12px
lg:flex
lg:flex-col
order-3
lg:order-2
w-full
2024-07-22 09:36:53 +02:00
>
2024-09-12 08:41:48 +02:00
<div
flex
flex-col
gap-4px
lg:grid
lg:grid-cols-10
lg:items-center
w-full
>
<h2>
Categories:
</h2>
<p
text-app-white
col-span-9
>
Dapp, Network
</p>
</div>
<div
flex
flex-col
gap-4px
lg:grid
lg:grid-cols-10
lg:items-center
w-full
>
<h2>
Ecosystems:
</h2>
<p
text-app-white
col-span-9
>
Ethereum, Secret Network
</p>
</div>
</div>
<div
grid
grid-cols-4
w-full
items-center
order-2
lg:order-3
>
2024-09-12 08:41:48 +02:00
<div
flex
items-center
justify-between
lg:justify-start
lg:gap-24px
col-span-3
>
<div
flex
flex-col
lg:flex-row
items-center
>
<p text="12px lg:16px" leading="16px lg:24px">Openess:</p>
<ProjectRating
:rating="project.ratings.openess"
type="openess"
:score="1"
compact
/>
</div>
<div
flex
flex-col
lg:flex-row
items-center
>
<p text="12px lg:16px" leading="16px lg:24px">Technology:</p>
<ProjectRating
:rating="project.ratings.technology"
type="technology"
:score="2"
compact
/>
</div>
<div
flex
flex-col
lg:flex-row
items-center
>
<p text="12px lg:16px" leading="16px lg:24px">Privacy:</p>
<ProjectRating
:rating="project.ratings.privacy"
type="privacy"
:score="3"
compact
/>
</div>
</div>
<div
flex
items-center
justify-end
w-full
gap-16px
mt--8px lg:mt-0
>
<h2
hidden
lg:block
>
Total Score:
</h2>
<div
flex
items-center
justify-center
border="2px app-white"
text="16px lg:24px app-white"
leading="24px md:32px"
max-h-="32px md:40px"
max-w="84px"
w-full
h-full
font-700
whitespace-nowrap
py="2px lg:8px"
lg:py-4px
>
{{ calculateScore }} %
</div>
</div>
</div>
2023-12-19 18:43:42 +01:00
</div>
</div>
</div>
</template>