2023-12-19 18:43:42 +01:00
|
|
|
<script lang="ts" setup>
|
2024-09-17 08:11:35 +02:00
|
|
|
import type { ProjectRating, ProjectShallow } from '~/types'
|
2023-12-19 18:43:42 +01:00
|
|
|
|
2024-09-12 08:42:37 +02:00
|
|
|
const props = defineProps<{
|
2023-12-19 18:43:42 +01:00
|
|
|
project: ProjectShallow
|
2024-10-03 15:59:25 +02:00
|
|
|
hiddenColumns?: string[]
|
2023-12-19 18:43:42 +01:00
|
|
|
}>()
|
2024-09-18 20:46:47 +02:00
|
|
|
const { switcher, ecosystems, filter } = storeToRefs(useData())
|
|
|
|
|
|
|
|
const isLargeScreen = useMediaQuery('(min-width: 1024px)')
|
2024-09-12 08:42:37 +02:00
|
|
|
|
2024-09-17 08:11:35 +02:00
|
|
|
const ratings: { label: string, type: string, rating: ProjectRating }[] = (props.project.ratings || []).map(rating => ({ label: rating.name, type: 'rating', rating: rating }))
|
|
|
|
const ecosystem: { label: string[], type: string } = { label: ecosystems.value.filter(e => (props.project.ecosystem || []).includes(e.id)).map(e => e.icon!), type: 'ecosystem' }
|
2024-09-17 08:23:56 +02:00
|
|
|
const projectItems: { label: string | string[], type: string, rating?: ProjectRating }[] = [{ label: props.project.usecases || [], type: 'array' }, ...ratings, ecosystem, { label: [props.project.website || '', props.project.github || '', props.project.twitter || ''], type: 'links' }]
|
2024-10-03 15:59:25 +02:00
|
|
|
|
|
|
|
const { width } = useWindowSize()
|
|
|
|
const visibleColumnsCount = computed(() => {
|
|
|
|
if (width.value >= 1024)
|
|
|
|
return projectItems.filter(item => item.rating?.type ? !props.hiddenColumns?.includes(item.rating.type) : true).length + 4
|
|
|
|
else
|
|
|
|
return 2
|
|
|
|
})
|
2023-12-19 18:43:42 +01:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<NuxtLink
|
|
|
|
:to="`/project/${project.id}`"
|
|
|
|
:class="switcher ? 'flex-row' : 'lg:flex-col'"
|
2024-09-02 15:13:43 +02:00
|
|
|
flex
|
|
|
|
w-full
|
|
|
|
gap-16px
|
|
|
|
hover:bg="#121212"
|
|
|
|
transition-all
|
2023-12-19 18:43:42 +01:00
|
|
|
>
|
2024-09-02 15:13:43 +02:00
|
|
|
<div
|
2024-09-12 08:42:37 +02:00
|
|
|
grid
|
2024-10-03 15:59:25 +02:00
|
|
|
:style="`grid-template-columns: repeat(${visibleColumnsCount}, 1fr)`"
|
2024-09-02 15:13:43 +02:00
|
|
|
w-full
|
|
|
|
>
|
2024-09-12 08:42:37 +02:00
|
|
|
|
2024-09-02 15:13:43 +02:00
|
|
|
<div
|
2024-09-17 08:11:35 +02:00
|
|
|
col-span="1 lg:2"
|
2024-09-02 15:13:43 +02:00
|
|
|
flex
|
|
|
|
items-center
|
2024-09-12 08:42:37 +02:00
|
|
|
gap="12px lg:16px"
|
|
|
|
relative
|
2024-09-02 15:13:43 +02:00
|
|
|
w-full
|
|
|
|
h-full
|
2024-09-12 08:42:37 +02:00
|
|
|
h="48px lg:64px"
|
|
|
|
:class="switcher ? '' : 'lg:max-w-full! lg:w-full '"
|
2024-09-02 15:13:43 +02:00
|
|
|
>
|
2024-09-24 19:51:28 +02:00
|
|
|
<NuxtImg
|
|
|
|
:src="project?.image || '/no-image-1-1.svg'"
|
|
|
|
class="w-full h-auto"
|
|
|
|
max-h="md:64px 48px"
|
|
|
|
max-w="md:64px 48px"
|
|
|
|
self-center
|
|
|
|
z-10
|
|
|
|
object-fit
|
|
|
|
bg="#121212"
|
|
|
|
/>
|
2024-09-02 15:13:43 +02:00
|
|
|
<div
|
|
|
|
flex
|
2024-09-12 08:42:37 +02:00
|
|
|
flex-col
|
|
|
|
gap-y-4px
|
|
|
|
lg:flex-row
|
|
|
|
justify-center
|
2024-09-02 15:13:43 +02:00
|
|
|
>
|
2024-09-12 08:42:37 +02:00
|
|
|
<div
|
|
|
|
w-fit
|
|
|
|
flex
|
|
|
|
items-center
|
|
|
|
gap-8px
|
|
|
|
>
|
|
|
|
<h1
|
2024-09-18 20:46:47 +02:00
|
|
|
flex
|
|
|
|
items-center
|
2024-09-12 08:42:37 +02:00
|
|
|
text="14px app-white"
|
|
|
|
font-700
|
|
|
|
line-clamp-1
|
|
|
|
hover:underline
|
|
|
|
underline-offset-3
|
|
|
|
leading="20px lg:32px"
|
2024-09-18 21:20:39 +02:00
|
|
|
class="relative inline-block"
|
2024-09-12 08:42:37 +02:00
|
|
|
>
|
|
|
|
{{ project.title1 }}
|
|
|
|
</h1>
|
|
|
|
</div>
|
|
|
|
<p
|
|
|
|
text-12px
|
|
|
|
leading-16px
|
|
|
|
lg:hidden
|
2024-09-27 12:14:49 +02:00
|
|
|
md:opacuty-100
|
|
|
|
opacity-70
|
2024-09-02 15:13:43 +02:00
|
|
|
>
|
2024-09-17 08:11:35 +02:00
|
|
|
{{ project.usecases?.join(', ') }}
|
2024-09-12 08:42:37 +02:00
|
|
|
</p>
|
2023-12-19 18:43:42 +01:00
|
|
|
</div>
|
2024-09-12 08:42:37 +02:00
|
|
|
</div>
|
2024-09-24 19:51:28 +02:00
|
|
|
<div
|
2024-10-03 15:59:25 +02:00
|
|
|
v-for="(projectItem, index) of projectItems.filter((item) => item.rating?.type ? !hiddenColumns?.includes(item.rating.type): true)"
|
2024-09-24 19:51:28 +02:00
|
|
|
:key="projectItem.label.toString()"
|
|
|
|
hidden
|
|
|
|
lg:flex
|
|
|
|
items-center
|
|
|
|
text-14px
|
|
|
|
leading-24px
|
|
|
|
:class="{ 'col-span-1 lg:col-span-2': index === 0 }"
|
|
|
|
>
|
|
|
|
<p
|
|
|
|
v-if="projectItem.type === 'array'"
|
|
|
|
text-app-text-grey
|
2024-09-02 15:13:43 +02:00
|
|
|
>
|
2024-09-24 19:51:28 +02:00
|
|
|
{{ (projectItem.label as string[] || []).join(', ') }}
|
|
|
|
</p>
|
2024-09-02 15:13:43 +02:00
|
|
|
<div
|
2024-09-24 19:51:28 +02:00
|
|
|
v-if="projectItem.type === 'links'"
|
2024-09-12 08:42:37 +02:00
|
|
|
flex
|
|
|
|
items-center
|
2024-09-24 19:51:28 +02:00
|
|
|
justify-start
|
2024-09-17 08:11:35 +02:00
|
|
|
gap-16px
|
2024-09-02 15:13:43 +02:00
|
|
|
>
|
2024-09-18 20:46:47 +02:00
|
|
|
<NuxtLink
|
2024-09-24 19:51:28 +02:00
|
|
|
v-if="projectItem.label[0]"
|
|
|
|
:to="projectItem.label[0]"
|
2024-09-18 20:46:47 +02:00
|
|
|
external
|
|
|
|
target="_blank"
|
|
|
|
@click.stop
|
|
|
|
>
|
|
|
|
<UnoIcon
|
2024-09-24 19:51:28 +02:00
|
|
|
i-ic-baseline-language
|
2024-09-27 12:14:49 +02:00
|
|
|
text="24px app-text-grey hover:app-white"
|
|
|
|
transition-all
|
|
|
|
duration-250
|
2024-09-18 20:46:47 +02:00
|
|
|
/>
|
2024-09-27 12:14:49 +02:00
|
|
|
|
2024-09-18 20:46:47 +02:00
|
|
|
</NuxtLink>
|
2024-09-24 19:51:28 +02:00
|
|
|
<NuxtLink
|
|
|
|
v-if="projectItem.label[1]"
|
|
|
|
:to="projectItem.label[1]"
|
|
|
|
external
|
|
|
|
target="_blank"
|
|
|
|
@click.stop
|
2024-09-17 08:11:35 +02:00
|
|
|
>
|
2024-09-24 19:51:28 +02:00
|
|
|
<UnoIcon
|
|
|
|
i-mdi-github
|
2024-09-27 12:14:49 +02:00
|
|
|
text="24px app-text-grey hover:app-white"
|
2024-09-24 19:51:28 +02:00
|
|
|
text-27px
|
2024-09-27 12:14:49 +02:00
|
|
|
transition-all
|
|
|
|
duration-250
|
2024-09-24 19:51:28 +02:00
|
|
|
/>
|
|
|
|
</NuxtLink>
|
|
|
|
<NuxtLink
|
|
|
|
v-if="projectItem.label[2]"
|
|
|
|
:to="projectItem.label[2]"
|
|
|
|
external
|
|
|
|
target="_blank"
|
|
|
|
@click.stop
|
|
|
|
>
|
|
|
|
<UnoIcon
|
|
|
|
i-bi-twitter-x
|
2024-09-27 12:14:49 +02:00
|
|
|
text="24px app-text-grey hover:app-white"
|
|
|
|
transition-all
|
|
|
|
duration-250
|
2024-09-24 19:51:28 +02:00
|
|
|
/>
|
|
|
|
</NuxtLink>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
v-if="projectItem.type === 'ecosystem'"
|
|
|
|
flex
|
|
|
|
items-center
|
|
|
|
justify-start
|
|
|
|
gap-2px
|
|
|
|
>
|
|
|
|
<NuxtImg
|
|
|
|
v-for="ecosystem of projectItem.label"
|
|
|
|
:key="ecosystem"
|
|
|
|
:src="ecosystem"
|
|
|
|
w-24px
|
|
|
|
h-24px
|
|
|
|
rounded-full
|
2024-09-18 20:46:47 +02:00
|
|
|
/>
|
2023-12-19 18:43:42 +01:00
|
|
|
</div>
|
2024-09-24 19:51:28 +02:00
|
|
|
<ProjectRating
|
|
|
|
v-if="projectItem.type! === 'rating' && projectItem.rating"
|
2024-09-25 20:31:41 +02:00
|
|
|
:percentage="projectItem.rating.percentagePoints"
|
2024-09-24 19:51:28 +02:00
|
|
|
:rating="projectItem.rating"
|
|
|
|
:type="projectItem.rating.type"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
flex
|
|
|
|
items-center
|
|
|
|
justify-end
|
|
|
|
w-full
|
|
|
|
gap-16px
|
|
|
|
>
|
|
|
|
<NuxtLink
|
|
|
|
v-if="project.website"
|
|
|
|
block
|
|
|
|
lg:hidden
|
|
|
|
:to="project.website"
|
|
|
|
external
|
|
|
|
target="_blank"
|
|
|
|
@click.stop
|
|
|
|
>
|
|
|
|
<UnoIcon
|
2024-09-12 08:42:37 +02:00
|
|
|
|
2024-09-24 19:51:28 +02:00
|
|
|
i-iconoir-internet
|
2024-09-27 12:14:49 +02:00
|
|
|
text="20px"
|
|
|
|
md:opacity-100
|
|
|
|
opacity-70
|
|
|
|
hover:opacity="100"
|
2024-09-24 19:51:28 +02:00
|
|
|
/>
|
|
|
|
</NuxtLink>
|
|
|
|
<div
|
|
|
|
v-if="filter.sortby === 'score' || filter.sortby === 'title' || isLargeScreen"
|
|
|
|
flex
|
|
|
|
items-center
|
|
|
|
justify-center
|
|
|
|
border="2px app-white"
|
|
|
|
text="14px md:18px"
|
|
|
|
leading="24px md:32px"
|
|
|
|
max-h-="28px md:32px"
|
|
|
|
max-w="48px md:56px"
|
|
|
|
w-full
|
|
|
|
font-700
|
|
|
|
whitespace-nowrap
|
|
|
|
>
|
|
|
|
{{ project.percentage }} %
|
|
|
|
</div>
|
|
|
|
<ProjectRating
|
|
|
|
v-if="(filter.sortby === 'openess' || filter.sortby === 'technology' || filter.sortby === 'privacy') && project.ratings?.find((r) => r.type === filter.sortby) && !isLargeScreen"
|
2024-09-25 20:31:41 +02:00
|
|
|
:percentage="project.ratings.find((r) => r.type === filter.sortby)!.percentagePoints"
|
2024-09-24 19:51:28 +02:00
|
|
|
:rating="project.ratings.find((r) => r.type === filter.sortby)!"
|
|
|
|
compact
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
2023-12-19 18:43:42 +01:00
|
|
|
</NuxtLink>
|
|
|
|
</template>
|