mirror of
https://github.com/BillyOutlast/drop.git
synced 2026-02-04 00:31:17 +01:00
feat: add store nav and fixes
This commit is contained in:
@@ -59,7 +59,6 @@ const emit = defineEmits<{
|
||||
|
||||
const open = defineModel<boolean>({ required: true });
|
||||
|
||||
const { t } = useI18n();
|
||||
const collectionName = ref("");
|
||||
const createCollectionLoading = ref(false);
|
||||
const collections = await useCollections();
|
||||
@@ -74,6 +73,7 @@ async function createCollection() {
|
||||
const response = await $dropFetch("/api/v1/collection", {
|
||||
method: "POST",
|
||||
body: { name: collectionName.value },
|
||||
failTitle: "Failed to create collection",
|
||||
});
|
||||
|
||||
// Add the game if provided
|
||||
@@ -83,6 +83,7 @@ async function createCollection() {
|
||||
>(`/api/v1/collection/${response.id}/entry`, {
|
||||
method: "POST",
|
||||
body: { id: props.gameId },
|
||||
failTitle: "Failed to add game to collection",
|
||||
});
|
||||
response.entries.push(entry);
|
||||
}
|
||||
@@ -94,20 +95,6 @@ async function createCollection() {
|
||||
open.value = false;
|
||||
|
||||
emit("created", response.id);
|
||||
} catch (error) {
|
||||
console.error("Failed to create collection:", error);
|
||||
|
||||
const err = error as { statusMessage?: string };
|
||||
createModal(
|
||||
ModalType.Notification,
|
||||
{
|
||||
title: t("errors.library.collection.create.title"),
|
||||
description: t("errors.library.collection.create.desc", [
|
||||
err?.statusMessage ?? t("errors.unknown"),
|
||||
]),
|
||||
},
|
||||
(_, c) => c(),
|
||||
);
|
||||
} finally {
|
||||
createCollectionLoading.value = false;
|
||||
}
|
||||
|
||||
39
components/UserHeader/StoreNav.vue
Normal file
39
components/UserHeader/StoreNav.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div
|
||||
class="w-full bg-zinc-950 p-1 inline-flex items-center gap-x-2 fixed inset-x-0 top-0 z-100"
|
||||
>
|
||||
<button
|
||||
class="p-1 text-zinc-300 hover:text-zinc-100 hover:bg-zinc-900 transition-all rounded"
|
||||
@click="() => router.back()"
|
||||
>
|
||||
<ChevronLeftIcon class="size-4" />
|
||||
</button>
|
||||
<button
|
||||
class="p-1 text-zinc-300 hover:text-zinc-100 hover:bg-zinc-900 transition-all rounded"
|
||||
@click="() => router.forward()"
|
||||
>
|
||||
<ChevronRightIcon class="size-4" />
|
||||
</button>
|
||||
<span class="text-zinc-400 text-sm">
|
||||
{{ title }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/vue/24/outline";
|
||||
|
||||
const router = useRouter();
|
||||
const title = ref("Loading...");
|
||||
|
||||
onMounted(() => {
|
||||
title.value = document.title;
|
||||
});
|
||||
|
||||
router.afterEach(() => {
|
||||
title.value = "Loading...";
|
||||
// TODO: more robust after-render "detection"
|
||||
setTimeout(() => {
|
||||
title.value = document.title;
|
||||
}, 500);
|
||||
});
|
||||
</script>
|
||||
@@ -1,12 +1,14 @@
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14-alpine
|
||||
user: "1000:1000"
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- ../.data/db:/var/lib/postgresql/data
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=drop
|
||||
- POSTGRES_USER=drop
|
||||
- POSTGRES_DB=drop
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
</div>
|
||||
<LazyUserFooter class="z-50" hydrate-on-interaction />
|
||||
</div>
|
||||
<div v-else class="flex w-full min-h-screen bg-zinc-900">
|
||||
<div v-else class="flex flex-col w-full min-h-screen bg-zinc-900">
|
||||
<NuxtPage />
|
||||
<LazyUserHeaderStoreNav />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ export default defineNuxtConfig({
|
||||
"https://images.pcgamingwiki.com",
|
||||
"https://images.igdb.com",
|
||||
"https://*.steamstatic.com",
|
||||
],
|
||||
]
|
||||
},
|
||||
strictTransportSecurity: false,
|
||||
},
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<AddLibraryButton :game-id="game.id" />
|
||||
</div>
|
||||
<NuxtLink
|
||||
v-if="user?.admin"
|
||||
v-if="user?.admin && !isClient"
|
||||
:href="`/admin/library/${game.id}`"
|
||||
type="button"
|
||||
class="inline-flex items-center gap-x-2 rounded-md bg-zinc-800 px-3 py-1 text-sm font-semibold font-display text-white shadow-sm hover:bg-zinc-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 duration-200 hover:scale-105 active:scale-95"
|
||||
@@ -254,6 +254,8 @@ const user = useUser();
|
||||
|
||||
const { game, rating, size } = await $dropFetch(`/api/v1/games/${gameId}`);
|
||||
|
||||
const isClient = isClientRequest();
|
||||
|
||||
const descriptionHTML = micromark(game.mDescription);
|
||||
|
||||
const platforms = game.versions
|
||||
|
||||
@@ -12,9 +12,17 @@ export default defineClientEventHandler(
|
||||
const acls: UserACL = [
|
||||
"read",
|
||||
"store:read",
|
||||
"collections:read",
|
||||
"object:read",
|
||||
"settings:read",
|
||||
|
||||
"collections:read",
|
||||
"collections:new",
|
||||
"collections:add",
|
||||
"collections:remove",
|
||||
"collections:delete",
|
||||
|
||||
"library:add",
|
||||
"library:remove"
|
||||
];
|
||||
|
||||
const token = await prisma.aPIToken.create({
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import { type } from "arktype";
|
||||
import { readDropValidatedBody, throwingArktype } from "~/server/arktype";
|
||||
import aclManager from "~/server/internal/acls";
|
||||
import userLibraryManager from "~/server/internal/userlibrary";
|
||||
|
||||
const CreateCollection = type({
|
||||
name: "string"
|
||||
}).configure(throwingArktype);
|
||||
|
||||
export default defineEventHandler(async (h3) => {
|
||||
const userId = await aclManager.getUserIdACL(h3, ["collections:read"]);
|
||||
const userId = await aclManager.getUserIdACL(h3, ["collections:new"]);
|
||||
if (!userId)
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
});
|
||||
|
||||
const body = await readBody(h3);
|
||||
|
||||
const name = body.name;
|
||||
if (!name)
|
||||
throw createError({ statusCode: 400, statusMessage: "Requires name" });
|
||||
const body = await readDropValidatedBody(h3, CreateCollection);
|
||||
|
||||
// Create the collection using the manager
|
||||
const newCollection = await userLibraryManager.collectionCreate(name, userId);
|
||||
const newCollection = await userLibraryManager.collectionCreate(body.name, userId);
|
||||
return newCollection;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user