mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-11 04:52:06 +10:00
feat(library admin): client side search
This commit is contained in:
@ -41,12 +41,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-2 grid grid-cols-1">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="search"
|
||||||
|
id="search"
|
||||||
|
class="col-start-1 row-start-1 block w-full rounded-md bg-zinc-900 py-1.5 pl-10 pr-3 text-base text-zinc-100 outline outline-1 -outline-offset-1 outline-zinc-700 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-blue-600 sm:pl-9 sm:text-sm/6"
|
||||||
|
placeholder="Search library..."
|
||||||
|
v-model="searchQuery"
|
||||||
|
/>
|
||||||
|
<MagnifyingGlassIcon
|
||||||
|
class="pointer-events-none col-start-1 row-start-1 ml-3 size-5 self-center text-zinc-400 sm:size-4"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<ul
|
<ul
|
||||||
role="list"
|
role="list"
|
||||||
class="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4"
|
class="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
v-for="game in libraryNotifications"
|
v-for="game in filteredLibraryGames"
|
||||||
:key="game.id"
|
:key="game.id"
|
||||||
class="col-span-1 flex flex-col justify-center divide-y divide-zinc-700 rounded-lg bg-zinc-950/20 text-left shadow"
|
class="col-span-1 flex flex-col justify-center divide-y divide-zinc-700 rounded-lg bg-zinc-950/20 text-left shadow"
|
||||||
>
|
>
|
||||||
@ -127,6 +141,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<p
|
||||||
|
class="text-zinc-600 text-sm font-display font-bold uppercase text-center col-span-4"
|
||||||
|
v-if="filteredLibraryGames.length == 0 && libraryGames.length != 0"
|
||||||
|
>
|
||||||
|
No results
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="text-zinc-600 text-sm font-display font-bold uppercase text-center col-span-4"
|
||||||
|
v-if="filteredLibraryGames.length == 0 && libraryGames.length == 0"
|
||||||
|
>
|
||||||
|
No games imported
|
||||||
|
</p>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -134,6 +160,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ExclamationTriangleIcon } from "@heroicons/vue/16/solid";
|
import { ExclamationTriangleIcon } from "@heroicons/vue/16/solid";
|
||||||
import { InformationCircleIcon } from "@heroicons/vue/20/solid";
|
import { InformationCircleIcon } from "@heroicons/vue/20/solid";
|
||||||
|
import { MagnifyingGlassIcon } from "@heroicons/vue/24/outline";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: "admin",
|
layout: "admin",
|
||||||
});
|
});
|
||||||
@ -142,9 +169,11 @@ useHead({
|
|||||||
title: "Libraries",
|
title: "Libraries",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const searchQuery = ref("");
|
||||||
|
|
||||||
const headers = useRequestHeaders(["cookie"]);
|
const headers = useRequestHeaders(["cookie"]);
|
||||||
const libraryState = await $fetch("/api/v1/admin/library", { headers });
|
const libraryState = await $fetch("/api/v1/admin/library", { headers });
|
||||||
const libraryNotifications = libraryState.games.map((e) => {
|
const libraryGames = libraryState.games.map((e) => {
|
||||||
const noVersions = e.status.noVersions;
|
const noVersions = e.status.noVersions;
|
||||||
const toImport = e.status.unimportedVersions.length > 0;
|
const toImport = e.status.unimportedVersions.length > 0;
|
||||||
|
|
||||||
@ -157,4 +186,15 @@ const libraryNotifications = libraryState.games.map((e) => {
|
|||||||
hasNotifications: noVersions || toImport,
|
hasNotifications: noVersions || toImport,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const filteredLibraryGames = computed(() =>
|
||||||
|
libraryGames.filter((e) => {
|
||||||
|
if (!searchQuery.value) return true;
|
||||||
|
const searchQueryLower = searchQuery.value.toLowerCase();
|
||||||
|
if (e.mName.toLowerCase().includes(searchQueryLower)) return true;
|
||||||
|
if (e.mShortDescription.toLowerCase().includes(searchQueryLower))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -109,6 +109,8 @@ const updated = await $fetch("/api/v1/store/updated", { headers });
|
|||||||
const released = await $fetch("/api/v1/store/released", {
|
const released = await $fetch("/api/v1/store/released", {
|
||||||
headers,
|
headers,
|
||||||
});
|
});
|
||||||
|
const developers = await $fetch("/api/v1/store/developers", { headers });
|
||||||
|
const publishers = await $fetch("/api/v1/store/publishers", { headers });
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: "Store",
|
title: "Store",
|
||||||
|
|||||||
20
server/api/v1/store/developers.ts
Normal file
20
server/api/v1/store/developers.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import prisma from "~/server/internal/db/database";
|
||||||
|
|
||||||
|
export default defineEventHandler(async (h3) => {
|
||||||
|
const userId = await h3.context.session.getUserId(h3);
|
||||||
|
if (!userId) throw createError({ statusCode: 403 });
|
||||||
|
|
||||||
|
const developers = await prisma.developer.findMany({
|
||||||
|
include: {
|
||||||
|
games: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
games: {
|
||||||
|
_count: "desc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
take: 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
return developers;
|
||||||
|
});
|
||||||
20
server/api/v1/store/publishers.ts
Normal file
20
server/api/v1/store/publishers.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import prisma from "~/server/internal/db/database";
|
||||||
|
|
||||||
|
export default defineEventHandler(async (h3) => {
|
||||||
|
const userId = await h3.context.session.getUserId(h3);
|
||||||
|
if (!userId) throw createError({ statusCode: 403 });
|
||||||
|
|
||||||
|
const publishers = await prisma.publisher.findMany({
|
||||||
|
include: {
|
||||||
|
games: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
games: {
|
||||||
|
_count: "desc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
take: 4,
|
||||||
|
});
|
||||||
|
|
||||||
|
return publishers;
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user