mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-14 00:31:25 +10:00
feat: add user platform filters to store view
This commit is contained in:
26
components/Icons/Platform.vue
Normal file
26
components/Icons/Platform.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<template>
|
||||
<component
|
||||
:is="platformIcons[props.platform as Platform]"
|
||||
v-if="platformIcons[props.platform as Platform]"
|
||||
/>
|
||||
<div v-else-if="props.fallback" v-html="props.fallback" />
|
||||
<DropLogo v-else />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Platform } from "~/prisma/client/enums";
|
||||
import type { Component } from "vue";
|
||||
import LinuxLogo from "./LinuxLogo.vue";
|
||||
import WindowsLogo from "./WindowsLogo.vue";
|
||||
import MacLogo from "./MacLogo.vue";
|
||||
import DropLogo from "../DropLogo.vue";
|
||||
|
||||
const props = defineProps<{ platform: string; fallback?: string }>();
|
||||
|
||||
const platformIcons: { [key in Platform]: Component } = {
|
||||
[Platform.Linux]: LinuxLogo,
|
||||
[Platform.Windows]: WindowsLogo,
|
||||
[Platform.macOS]: MacLogo,
|
||||
};
|
||||
</script>
|
||||
@ -247,7 +247,7 @@
|
||||
<div
|
||||
v-for="(option, optionIdx) in section.options"
|
||||
:key="option.param"
|
||||
class="flex gap-3"
|
||||
class="flex items-center gap-3"
|
||||
>
|
||||
<div class="flex h-5 shrink-0 items-center">
|
||||
<div class="group grid size-4 grid-cols-1">
|
||||
@ -272,6 +272,12 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<IconsPlatform
|
||||
v-if="option.platformIcon"
|
||||
:platform="option.platformIcon.key"
|
||||
:fallback="option.platformIcon.fallback"
|
||||
class="size-5 text-blue-500"
|
||||
/>
|
||||
<label
|
||||
:for="`filter-${section.param}-${optionIdx}`"
|
||||
class="text-sm text-zinc-400"
|
||||
@ -411,8 +417,16 @@ const options: Array<StoreFilterOption> = [
|
||||
param: "platform",
|
||||
multiple: true,
|
||||
options: [
|
||||
...Object.values(Platform).map((e) => ({ name: e, param: e })),
|
||||
...userPlatforms.map((e) => ({ name: e.platformName, param: e.id })),
|
||||
...Object.values(Platform).map((e) => ({
|
||||
name: e,
|
||||
param: e,
|
||||
platformIcon: { key: e },
|
||||
})),
|
||||
...userPlatforms.map((e) => ({
|
||||
name: e.platformName,
|
||||
param: e.id,
|
||||
platformIcon: { key: e.id, fallback: e.iconSvg },
|
||||
})),
|
||||
],
|
||||
},
|
||||
...(props.extraOptions ?? []),
|
||||
|
||||
@ -8,4 +8,5 @@ export type StoreFilterOption = {
|
||||
export type StoreSortOption = {
|
||||
name: string;
|
||||
param: string;
|
||||
platformIcon?: { key: string; fallback?: string };
|
||||
};
|
||||
|
||||
@ -73,18 +73,18 @@
|
||||
<td
|
||||
class="whitespace-nowrap inline-flex gap-x-4 px-3 py-4 text-sm text-zinc-400"
|
||||
>
|
||||
<div
|
||||
<IconsPlatform
|
||||
v-for="platform in platforms"
|
||||
:key="typeof platform === 'string' ? platform : platform.id"
|
||||
>
|
||||
<component
|
||||
:is="PLATFORM_ICONS[platform]"
|
||||
v-if="typeof platform === 'string'"
|
||||
class="text-blue-600 w-6 h-6"
|
||||
/>
|
||||
<div v-else class="text-blue-600 w-6 h-6" v-html="platform.iconSvg" />
|
||||
</div>
|
||||
|
||||
:platform="
|
||||
typeof platform === 'string' ? platform : platform.id
|
||||
"
|
||||
:fallback="
|
||||
typeof platform === 'string'
|
||||
? undefined
|
||||
: platform.iconSvg
|
||||
"
|
||||
/>
|
||||
<span
|
||||
v-if="platforms.length == 0"
|
||||
class="font-display uppercase font-bold text-zinc-700"
|
||||
|
||||
@ -10,6 +10,7 @@ export default defineEventHandler(async (h3) => {
|
||||
select: {
|
||||
id: true,
|
||||
platformName: true,
|
||||
iconSvg: true,
|
||||
},
|
||||
});
|
||||
return platforms;
|
||||
|
||||
Reference in New Issue
Block a user