feat(games): add games to disable + path

This commit is contained in:
2026-05-23 14:18:44 +02:00
parent 9f94fb3974
commit 544112b204
20 changed files with 235 additions and 27 deletions
+23 -25
View File
@@ -1,22 +1,10 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import { ref, onMounted } from "vue";
import { apiService } from "./services/apiService";
import type { Game } from "./types";
const games = computed(() => [
{
id: "opus-magnum",
title: "Opus Magnum",
description: "Submit your best Opus Magnum puzzle solutions",
appId: 558990,
path: "/opus-magnum",
},
{
id: "noita",
title: "Noita",
description: "Submit your greatest Noita achievements",
appId: 881100,
path: "/noita",
},
]);
const games = ref<Game[]>([]);
const loading = ref(true);
const imageErrors = ref<Set<number>>(new Set());
@@ -31,6 +19,14 @@ const onImageError = (appId: number) => {
const navigate = (path: string) => {
window.location.href = path;
};
onMounted(async () => {
const response = await apiService.getGames();
if (response.data) {
games.value = response.data;
}
loading.value = false;
});
</script>
<template>
@@ -44,13 +40,18 @@ const navigate = (path: string) => {
</p>
</div>
<!-- Loading -->
<div v-if="loading" class="flex justify-center py-20">
<span class="loading loading-spinner loading-lg"></span>
</div>
<!-- Cards Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div v-for="game in games" :key="game.id" @click="navigate(game.path)"
<div v-else class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div v-for="game in games" :key="game.steam_app_id" @click="navigate(game.path)"
class="card card-xl bg-base-200 shadow-xl hover:shadow-2xl transition-all cursor-pointer transform hover:-translate-y-2 hover:scale-[1.05] hover:bg-base-100 overflow-hidden">
<figure class="relative h-60 bg-base-300 overflow-hidden">
<img v-if="!imageErrors.has(game.appId)" :src="getHeaderImage(game.appId)" :alt="game.title"
@error="onImageError(game.appId)" class="w-full h-full object-cover" />
<img v-if="!imageErrors.has(game.steam_app_id)" :src="getHeaderImage(game.steam_app_id)" :alt="game.name"
@error="onImageError(game.steam_app_id)" class="w-full h-full object-cover" />
<div v-else
class="w-full h-full bg-gradient-to-br from-blue-600 to-blue-400 flex items-center justify-center text-white">
<i class="mdi mdi-gamepad-variant text-5xl"></i>
@@ -58,8 +59,7 @@ const navigate = (path: string) => {
<div class="absolute inset-0 bg-black/30 group-hover:bg-black/20 transition-colors"></div>
</figure>
<div class="card-body">
<h2 class="card-title text-2xl">{{ game.title }}</h2>
<p class="text-base-content/70">{{ game.description }}</p>
<h2 class="card-title text-2xl">{{ game.name }}</h2>
<div class="card-actions justify-end mt-4">
<button class="btn btn-primary">
<i class="mdi mdi-arrow-right mr-2"></i>
@@ -75,7 +75,5 @@ const navigate = (path: string) => {
<p>Select a game above to begin submitting</p>
</div>
</div>
</div>
</template>
@@ -1,4 +1,5 @@
import type {
Game,
SteamCollection,
SteamCollectionItem,
Submission,
@@ -99,6 +100,11 @@ export class ApiService {
}
}
// Games endpoint
async getGames(): Promise<ApiResponse<Game[]>> {
return this.request<Game[]>('/games/')
}
// Puzzle endpoints
async getPuzzles(): Promise<ApiResponse<SteamCollectionItem[]>> {
return this.request<SteamCollectionItem[]>('/submissions/puzzles')
+6
View File
@@ -1,3 +1,9 @@
export interface Game {
steam_app_id: number
name: string
path: string
}
export interface SteamCollection {
id: number
steam_id: string