Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 2 additions & 15 deletions components/Modal/CreateCollection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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
Expand All @@ -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);
}
Expand All @@ -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;
}
Expand Down
39 changes: 39 additions & 0 deletions components/UserHeader/StoreNav.vue
Original file line number Diff line number Diff line change
@@ -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>
6 changes: 4 additions & 2 deletions dev-tools/compose.yml
Original file line number Diff line number Diff line change
@@ -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:
3 changes: 2 additions & 1 deletion layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
2 changes: 1 addition & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export default defineNuxtConfig({
"https://images.pcgamingwiki.com",
"https://images.igdb.com",
"https://*.steamstatic.com",
],
]
},
strictTransportSecurity: false,
},
Expand Down
4 changes: 3 additions & 1 deletion pages/store/[id]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion server/api/v1/client/user/webtoken.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
16 changes: 9 additions & 7 deletions server/api/v1/collection/index.post.ts
Original file line number Diff line number Diff line change
@@ -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;
});
Loading