mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-12 15:52:39 +10:00
feat: user page & $dropFetch util
This commit is contained in:
@ -7,15 +7,24 @@
|
||||
<div
|
||||
class="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-l-[calc(2rem+1px)]"
|
||||
>
|
||||
<div class="px-8 pt-8 pb-3 sm:px-10 sm:pt-10 sm:pb-0">
|
||||
<div class="px-8 pt-8 pb-3 sm:px-10 sm:py-10">
|
||||
<p
|
||||
class="mt-2 text-lg font-medium tracking-tight text-zinc-100 max-lg:text-center"
|
||||
>
|
||||
Library
|
||||
</p>
|
||||
<p class="mt-2 max-w-lg text-sm/6 text-zinc-400 max-lg:text-center">
|
||||
Anim aute id magna aliqua ad ad non deserunt sunt. Qui irure qui
|
||||
lorem cupidatat commodo.
|
||||
Manage your Drop library, and import new games. Your library is the
|
||||
list of all games currently configured on this instance.
|
||||
</p>
|
||||
<p class="mt-3 text-sm">
|
||||
<NuxtLink
|
||||
href="/admin/library"
|
||||
class="whitespace-nowrap font-medium text-blue-400 hover:text-blue-500"
|
||||
>
|
||||
Check it out
|
||||
<span aria-hidden="true"> →</span>
|
||||
</NuxtLink>
|
||||
</p>
|
||||
|
||||
<div
|
||||
@ -45,31 +54,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dl
|
||||
class="mt-4 grid max-w-xl grid-cols-1 gap-8 sm:grid-cols-2 xl:mt-8"
|
||||
>
|
||||
<div class="flex flex-col gap-y-3 border-l border-zinc-100/10 pl-6">
|
||||
<dt class="text-sm/6 text-zinc-400">Games</dt>
|
||||
<dd
|
||||
class="order-first text-3xl font-semibold tracking-tight text-zinc-100"
|
||||
>
|
||||
{{ libraryState.games.length }}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="flex flex-col gap-y-3 border-l border-zinc-100/10 pl-6">
|
||||
<dt class="text-sm/6 text-zinc-400">Versions</dt>
|
||||
<dd
|
||||
class="order-first text-3xl font-semibold tracking-tight text-zinc-100"
|
||||
>
|
||||
{{
|
||||
libraryState.games
|
||||
.map((e) => e.game.versions.length)
|
||||
.reduce((a, b) => a + b, 0)
|
||||
}}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -78,30 +62,30 @@
|
||||
</div>
|
||||
<div class="relative max-lg:row-start-1">
|
||||
<div
|
||||
class="absolute inset-px rounded-lg bg-white max-lg:rounded-t-[2rem]"
|
||||
class="absolute inset-px rounded-lg bg-zinc-950 max-lg:rounded-t-[2rem]"
|
||||
/>
|
||||
<div
|
||||
class="relative flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)]"
|
||||
>
|
||||
<div class="px-8 pt-8 sm:px-10 sm:pt-10">
|
||||
<div class="px-8 py-8 sm:px-10 sm:py-10">
|
||||
<p
|
||||
class="mt-2 text-lg font-medium tracking-tight text-gray-950 max-lg:text-center"
|
||||
class="mt-2 text-lg font-medium tracking-tight text-zinc-100 max-lg:text-center"
|
||||
>
|
||||
Performance
|
||||
Users
|
||||
</p>
|
||||
<p class="mt-2 max-w-lg text-sm/6 text-gray-600 max-lg:text-center">
|
||||
Lorem ipsum, dolor sit amet consectetur adipisicing elit maiores
|
||||
impedit.
|
||||
<p class="mt-2 max-w-lg text-sm/6 text-zinc-400 max-lg:text-center">
|
||||
Your users are people who can access your Drop instance, download
|
||||
games from it, and configure API keys for it.
|
||||
</p>
|
||||
<p class="mt-3 text-sm">
|
||||
<NuxtLink
|
||||
href="/admin/users"
|
||||
class="whitespace-nowrap font-medium text-blue-400 hover:text-blue-500"
|
||||
>
|
||||
Check it out
|
||||
<span aria-hidden="true"> →</span>
|
||||
</NuxtLink>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-1 items-center justify-center px-8 max-lg:pt-10 max-lg:pb-12 sm:px-10 lg:pb-2"
|
||||
>
|
||||
<img
|
||||
class="w-full max-lg:max-w-xs"
|
||||
src="https://tailwindcss.com/plus-assets/img/component-images/bento-03-performance.png"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -193,5 +177,5 @@ useHead({
|
||||
});
|
||||
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const libraryState = await $fetch("/api/v1/admin/library", { headers });
|
||||
const libraryState = await $dropFetch("/api/v1/admin/library", { headers });
|
||||
</script>
|
||||
|
||||
@ -165,7 +165,7 @@
|
||||
'relative cursor-default select-none py-2 pl-3 pr-9',
|
||||
active
|
||||
? 'bg-blue-600 text-white outline-none'
|
||||
: 'text-gray-900',
|
||||
: 'text-zinc-100',
|
||||
]"
|
||||
>
|
||||
<span
|
||||
@ -321,7 +321,7 @@
|
||||
'relative cursor-default select-none py-2 pl-3 pr-9',
|
||||
active
|
||||
? 'bg-blue-600 text-white outline-none'
|
||||
: 'text-gray-900',
|
||||
: 'text-zinc-100',
|
||||
]"
|
||||
>
|
||||
<span
|
||||
@ -553,7 +553,7 @@ const router = useRouter();
|
||||
const route = useRoute();
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const gameId = route.params.id.toString();
|
||||
const versions = await $fetch(
|
||||
const versions = await $dropFetch(
|
||||
`/api/v1/admin/import/version?id=${encodeURIComponent(gameId)}`,
|
||||
{
|
||||
headers,
|
||||
@ -561,7 +561,7 @@ const versions = await $fetch(
|
||||
);
|
||||
const currentlySelectedVersion = ref(-1);
|
||||
const versionSettings = ref<{
|
||||
platform: string;
|
||||
platform: PlatformClient | undefined;
|
||||
|
||||
onlySetup: boolean;
|
||||
launch: string;
|
||||
@ -572,7 +572,7 @@ const versionSettings = ref<{
|
||||
delta: boolean;
|
||||
umuId: string;
|
||||
}>({
|
||||
platform: "",
|
||||
platform: undefined,
|
||||
launch: "",
|
||||
launchArgs: "",
|
||||
setup: "",
|
||||
@ -582,7 +582,8 @@ const versionSettings = ref<{
|
||||
umuId: "",
|
||||
});
|
||||
|
||||
const versionGuesses = ref<Array<{ platform: string; filename: string }>>();
|
||||
const versionGuesses =
|
||||
ref<Array<{ platform: PlatformClient; filename: string }>>();
|
||||
const launchProcessQuery = ref("");
|
||||
const setupProcessQuery = ref("");
|
||||
|
||||
@ -637,17 +638,20 @@ async function updateCurrentlySelectedVersion(value: number) {
|
||||
if (currentlySelectedVersion.value == value) return;
|
||||
currentlySelectedVersion.value = value;
|
||||
const version = versions[currentlySelectedVersion.value];
|
||||
const results = await $fetch(
|
||||
const results = await $dropFetch(
|
||||
`/api/v1/admin/import/version/preload?id=${encodeURIComponent(
|
||||
gameId
|
||||
)}&version=${encodeURIComponent(version)}`
|
||||
);
|
||||
versionGuesses.value = results;
|
||||
versionGuesses.value = results.map((e) => ({
|
||||
...e,
|
||||
platform: e.platform as PlatformClient,
|
||||
}));
|
||||
}
|
||||
|
||||
async function startImport() {
|
||||
if (!versionSettings.value) return;
|
||||
const taskId = await $fetch("/api/v1/admin/import/version", {
|
||||
const taskId = await $dropFetch("/api/v1/admin/import/version", {
|
||||
method: "POST",
|
||||
body: {
|
||||
id: gameId,
|
||||
|
||||
@ -530,7 +530,7 @@ const mobileShowFinalDescription = ref(true);
|
||||
const route = useRoute();
|
||||
const gameId = route.params.id.toString();
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const { game: rawGame, unimportedVersions } = await $fetch(
|
||||
const { game: rawGame, unimportedVersions } = await $dropFetch(
|
||||
`/api/v1/admin/game?id=${encodeURIComponent(gameId)}`,
|
||||
{
|
||||
headers,
|
||||
@ -579,7 +579,7 @@ async function coreMetadataUpdate() {
|
||||
formData.append("name", coreMetadataName.value);
|
||||
formData.append("description", coreMetadataDescription.value);
|
||||
|
||||
const result = await $fetch(`/api/v1/admin/game/metadata`, {
|
||||
const result = await $dropFetch(`/api/v1/admin/game/metadata`, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
});
|
||||
@ -630,7 +630,7 @@ watch(descriptionHTML, (v) => {
|
||||
savingTimeout = setTimeout(async () => {
|
||||
try {
|
||||
descriptionSaving.value = 2;
|
||||
await $fetch("/api/v1/admin/game", {
|
||||
await $dropFetch("/api/v1/admin/game", {
|
||||
method: "PATCH",
|
||||
body: {
|
||||
id: gameId,
|
||||
@ -672,7 +672,7 @@ function insertImageAtCursor(id: string) {
|
||||
async function updateBannerImage(id: string) {
|
||||
try {
|
||||
if (game.value.mBannerId == id) return;
|
||||
const { mBannerId } = await $fetch("/api/v1/admin/game", {
|
||||
const { mBannerId } = await $dropFetch("/api/v1/admin/game", {
|
||||
method: "PATCH",
|
||||
body: {
|
||||
id: gameId,
|
||||
@ -698,7 +698,7 @@ async function updateBannerImage(id: string) {
|
||||
async function updateCoverImage(id: string) {
|
||||
try {
|
||||
if (game.value.mCoverId == id) return;
|
||||
const { mCoverId } = await $fetch("/api/v1/admin/game", {
|
||||
const { mCoverId } = await $dropFetch("/api/v1/admin/game", {
|
||||
method: "PATCH",
|
||||
body: {
|
||||
id: gameId,
|
||||
@ -723,7 +723,7 @@ async function updateCoverImage(id: string) {
|
||||
|
||||
async function deleteImage(id: string) {
|
||||
try {
|
||||
const { mBannerId, mImageLibrary } = await $fetch(
|
||||
const { mBannerId, mImageLibrary } = await $dropFetch(
|
||||
"/api/v1/admin/game/image",
|
||||
{
|
||||
method: "DELETE",
|
||||
@ -757,7 +757,7 @@ async function uploadAfterImageUpload(result: Game) {
|
||||
|
||||
async function deleteVersion(versionName: string) {
|
||||
try {
|
||||
await $fetch("/api/v1/admin/game/version", {
|
||||
await $dropFetch("/api/v1/admin/game/version", {
|
||||
method: "DELETE",
|
||||
body: {
|
||||
id: gameId,
|
||||
@ -785,7 +785,7 @@ async function deleteVersion(versionName: string) {
|
||||
|
||||
async function updateVersionOrder() {
|
||||
try {
|
||||
const newVersions = await $fetch("/api/v1/admin/game/version", {
|
||||
const newVersions = await $dropFetch("/api/v1/admin/game/version", {
|
||||
method: "PATCH",
|
||||
body: {
|
||||
id: gameId,
|
||||
@ -822,7 +822,7 @@ function removeImageFromCarousel(id: string) {
|
||||
|
||||
async function updateImageCarousel() {
|
||||
try {
|
||||
await $fetch("/api/v1/admin/game", {
|
||||
await $dropFetch("/api/v1/admin/game", {
|
||||
method: "PATCH",
|
||||
body: {
|
||||
id: gameId,
|
||||
|
||||
@ -158,7 +158,7 @@ definePageMeta({
|
||||
});
|
||||
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const games = await $fetch("/api/v1/admin/import/game", { headers });
|
||||
const games = await $dropFetch("/api/v1/admin/import/game", { headers });
|
||||
|
||||
const currentlySelectedGame = ref(-1);
|
||||
const gameSearchResultsLoading = ref(false);
|
||||
@ -174,7 +174,7 @@ async function updateSelectedGame(value: number) {
|
||||
metadataResults.value = undefined;
|
||||
currentlySelectedMetadata.value = -1;
|
||||
|
||||
const results = await $fetch(
|
||||
const results = await $dropFetch(
|
||||
`/api/v1/admin/import/game/search?q=${encodeURIComponent(game)}`
|
||||
);
|
||||
metadataResults.value = results;
|
||||
@ -199,7 +199,7 @@ const importError = ref<string | undefined>();
|
||||
async function importGame(metadata: boolean) {
|
||||
if (!metadataResults.value && metadata) return;
|
||||
|
||||
const game = await $fetch("/api/v1/admin/import/game", {
|
||||
const game = await $dropFetch("/api/v1/admin/import/game", {
|
||||
method: "POST",
|
||||
body: {
|
||||
path: games.unimportedGames[currentlySelectedGame.value],
|
||||
|
||||
@ -180,7 +180,7 @@ useHead({
|
||||
const searchQuery = ref("");
|
||||
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const libraryState = await $fetch("/api/v1/admin/library", { headers });
|
||||
const libraryState = await $dropFetch("/api/v1/admin/library", { headers });
|
||||
const libraryGames = ref(
|
||||
libraryState.games.map((e) => {
|
||||
const noVersions = e.status.noVersions;
|
||||
@ -210,7 +210,7 @@ const filteredLibraryGames = computed(() =>
|
||||
);
|
||||
|
||||
async function deleteGame(id: string) {
|
||||
await $fetch(`/api/v1/admin/game?id=${id}`, { method: "DELETE" });
|
||||
await $dropFetch(`/api/v1/admin/game?id=${id}`, { method: "DELETE" });
|
||||
const index = libraryGames.value.findIndex((e) => e.id === id);
|
||||
libraryGames.value.splice(index, 1);
|
||||
}
|
||||
|
||||
11
pages/admin/metadata/index.vue
Normal file
11
pages/admin/metadata/index.vue
Normal file
@ -0,0 +1,11 @@
|
||||
<template></template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: "admin",
|
||||
});
|
||||
|
||||
useHead({
|
||||
title: "Metadata",
|
||||
});
|
||||
</script>
|
||||
@ -23,9 +23,7 @@
|
||||
:key="authMech.name"
|
||||
class="overflow-hidden rounded-xl border border-zinc-800 bg-zinc-900"
|
||||
>
|
||||
<div
|
||||
class="flex items-center gap-x-4 border-b border-zinc-800 p-6"
|
||||
>
|
||||
<div class="flex items-center gap-x-4 border-b border-zinc-800 p-6">
|
||||
<component
|
||||
:is="authMech.icon"
|
||||
:alt="`${authMech.name} icon`"
|
||||
@ -101,23 +99,9 @@ import { IconsSimpleAuthenticationLogo } from "#components";
|
||||
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/vue";
|
||||
import { EllipsisHorizontalIcon } from "@heroicons/vue/20/solid";
|
||||
import { CheckIcon, XMarkIcon } from "@heroicons/vue/24/solid";
|
||||
import { AuthMec } from "@prisma/client";
|
||||
import type { Component } from "vue";
|
||||
|
||||
const authenticationMechanisms: Array<{
|
||||
name: string;
|
||||
enabled: boolean;
|
||||
icon: Component;
|
||||
route: string;
|
||||
settings?: { [key: string]: string };
|
||||
}> = [
|
||||
{
|
||||
name: "Simple (username/password)",
|
||||
enabled: true,
|
||||
icon: IconsSimpleAuthenticationLogo,
|
||||
route: "/admin/auth/simple",
|
||||
},
|
||||
];
|
||||
|
||||
useHead({
|
||||
title: "Authentication",
|
||||
});
|
||||
@ -125,4 +109,25 @@ useHead({
|
||||
definePageMeta({
|
||||
layout: "admin",
|
||||
});
|
||||
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const enabledMechanisms = await $dropFetch("/api/v1/admin/auth", {
|
||||
headers,
|
||||
});
|
||||
|
||||
const authenticationMechanisms: Array<{
|
||||
name: string;
|
||||
mec: AuthMec;
|
||||
icon: Component;
|
||||
route: string;
|
||||
enabled: boolean;
|
||||
settings?: { [key: string]: string };
|
||||
}> = [
|
||||
{
|
||||
name: "Simple (username/password)",
|
||||
mec: AuthMec.Simple,
|
||||
icon: IconsSimpleAuthenticationLogo,
|
||||
route: "/admin/users/auth/simple",
|
||||
},
|
||||
].map((e) => ({ ...e, enabled: enabledMechanisms.includes(e.mec) }));
|
||||
</script>
|
||||
@ -459,7 +459,7 @@ async function invite() {
|
||||
.add(...expiry[expiryKey.value])
|
||||
.toJSON();
|
||||
|
||||
const newInvitation = await $fetch("/api/v1/admin/auth/invitation", {
|
||||
const newInvitation = await $dropFetch("/api/v1/admin/auth/invitation", {
|
||||
method: "POST",
|
||||
body: {
|
||||
username: username.value,
|
||||
@ -495,7 +495,7 @@ function invite_wrapper() {
|
||||
}
|
||||
|
||||
async function deleteInvitation(id: string) {
|
||||
await $fetch("/api/v1/admin/auth/invitation", {
|
||||
await $dropFetch("/api/v1/admin/auth/invitation", {
|
||||
method: "DELETE",
|
||||
body: {
|
||||
id: id,
|
||||
111
pages/admin/users/index.vue
Normal file
111
pages/admin/users/index.vue
Normal file
@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="sm:flex sm:items-center">
|
||||
<div class="sm:flex-auto">
|
||||
<h1 class="text-base font-semibold text-zinc-100">Users</h1>
|
||||
<p class="mt-2 text-sm text-zinc-400">
|
||||
Manage the users on your Drop instance, and configure your
|
||||
authentication methods.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
|
||||
<NuxtLink
|
||||
to="/admin/users/auth"
|
||||
class="block rounded-md bg-blue-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
|
||||
>
|
||||
Authentication →
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 flow-root">
|
||||
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
|
||||
<table class="min-w-full divide-y divide-zinc-700">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-zinc-100 sm:pl-3"
|
||||
>
|
||||
Display Name
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-3.5 text-left text-sm font-semibold text-zinc-100"
|
||||
>
|
||||
Username
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-3.5 text-left text-sm font-semibold text-zinc-100"
|
||||
>
|
||||
Email
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-3.5 text-left text-sm font-semibold text-zinc-100"
|
||||
>
|
||||
Admin?
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-3.5 text-left text-sm font-semibold text-zinc-100"
|
||||
>
|
||||
Auth Options
|
||||
</th>
|
||||
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-3">
|
||||
<span class="sr-only">Edit</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="user in users" :key="user.id" class="even:bg-zinc-800">
|
||||
<td
|
||||
class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-zinc-100 sm:pl-3"
|
||||
>
|
||||
{{ user.displayName }}
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-zinc-400">
|
||||
{{ user.username }}
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-zinc-400">
|
||||
{{ user.email }}
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-zinc-400">
|
||||
{{ user.admin ? "Admin User" : "Normal user" }}
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-zinc-400">
|
||||
{{ user.authMecs.map((e) => e.mec).join(", ") }}
|
||||
</td>
|
||||
<td
|
||||
class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-3"
|
||||
>
|
||||
<!--
|
||||
<a href="#" class="text-blue-600 hover:text-blue-500"
|
||||
>Edit<span class="sr-only"
|
||||
>, {{ user.displayName }}</span
|
||||
></a
|
||||
>
|
||||
-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
useHead({
|
||||
title: "Users",
|
||||
});
|
||||
|
||||
definePageMeta({
|
||||
layout: "admin",
|
||||
});
|
||||
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const { data: users } = await useFetch("/api/v1/admin/users", { headers });
|
||||
</script>
|
||||
@ -175,7 +175,7 @@ const error = ref();
|
||||
const authToken = ref<string | undefined>();
|
||||
|
||||
async function authorize() {
|
||||
const { redirect, token } = await $fetch("/api/v1/client/auth/callback", {
|
||||
const { redirect, token } = await $dropFetch("/api/v1/client/auth/callback", {
|
||||
method: "POST",
|
||||
body: { id: clientId },
|
||||
});
|
||||
|
||||
@ -224,7 +224,7 @@ const loading = ref(false);
|
||||
const error = ref<string | undefined>(undefined);
|
||||
|
||||
async function register() {
|
||||
await $fetch("/api/v1/auth/signup/simple", {
|
||||
await $dropFetch("/api/v1/auth/signup/simple", {
|
||||
method: "POST",
|
||||
body: {
|
||||
invitation: invitationId,
|
||||
|
||||
@ -149,7 +149,7 @@ function signin_wrapper() {
|
||||
}
|
||||
|
||||
async function signin() {
|
||||
await $fetch("/api/v1/auth/signin/simple", {
|
||||
await $dropFetch("/api/v1/auth/signin/simple", {
|
||||
method: "POST",
|
||||
body: {
|
||||
username: username.value,
|
||||
@ -158,7 +158,7 @@ async function signin() {
|
||||
},
|
||||
});
|
||||
const user = useUser();
|
||||
user.value = await $fetch<User | null>("/api/v1/user");
|
||||
user.value = await $dropFetch<User | null>("/api/v1/user");
|
||||
}
|
||||
|
||||
definePageMeta({
|
||||
|
||||
@ -36,6 +36,6 @@ const user = useUser();
|
||||
user.value = null;
|
||||
|
||||
// Redirect to signin page after signout
|
||||
await $fetch("/signout");
|
||||
await $dropFetch("/signout");
|
||||
router.push("/signin");
|
||||
</script>
|
||||
|
||||
@ -177,7 +177,7 @@ const gameId = route.params.id.toString();
|
||||
const user = useUser();
|
||||
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const game = await $fetch<Game & { versions: GameVersion[] }>(
|
||||
const game = await $dropFetch<Game & { versions: GameVersion[] }>(
|
||||
`/api/v1/games/${gameId}`,
|
||||
{ headers }
|
||||
);
|
||||
|
||||
@ -96,13 +96,13 @@
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
const headers = useRequestHeaders(["cookie"]);
|
||||
const recent = await $fetch("/api/v1/store/recent", { headers });
|
||||
const updated = await $fetch("/api/v1/store/updated", { headers });
|
||||
const released = await $fetch("/api/v1/store/released", {
|
||||
const recent = await $dropFetch("/api/v1/store/recent", { headers });
|
||||
const updated = await $dropFetch("/api/v1/store/updated", { headers });
|
||||
const released = await $dropFetch("/api/v1/store/released", {
|
||||
headers,
|
||||
});
|
||||
const developers = await $fetch("/api/v1/store/developers", { headers });
|
||||
const publishers = await $fetch("/api/v1/store/publishers", { headers });
|
||||
const developers = await $dropFetch("/api/v1/store/developers", { headers });
|
||||
const publishers = await $dropFetch("/api/v1/store/publishers", { headers });
|
||||
|
||||
useHead({
|
||||
title: "Store",
|
||||
|
||||
Reference in New Issue
Block a user