basic noita parsing
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue";
|
||||
import { ref, onMounted } from "vue";
|
||||
|
||||
interface Objective {
|
||||
objectiv_id: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
const userInfo = ref({
|
||||
username: "Player",
|
||||
@@ -11,6 +16,8 @@ const userInfo = ref({
|
||||
const uploadedFiles = ref<File[]>([]);
|
||||
const isUploading = ref(false);
|
||||
const isDragover = ref(false);
|
||||
const objectives = ref<Objective[]>([]);
|
||||
const isLoadingObjectives = ref(false);
|
||||
|
||||
const handleFileUpload = (event: Event) => {
|
||||
const input = event.target as HTMLInputElement;
|
||||
@@ -78,6 +85,24 @@ const submitRun = async () => {
|
||||
const goHome = () => {
|
||||
window.location.href = "/";
|
||||
};
|
||||
|
||||
const fetchObjectives = async () => {
|
||||
isLoadingObjectives.value = true;
|
||||
try {
|
||||
const response = await fetch("/api/noita/objectives");
|
||||
if (!response.ok) throw new Error("Failed to fetch objectives");
|
||||
|
||||
objectives.value = await response.json();
|
||||
} catch (error) {
|
||||
console.error("Error fetching objectives:", error);
|
||||
} finally {
|
||||
isLoadingObjectives.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchObjectives();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -149,25 +174,15 @@ const goHome = () => {
|
||||
</h2>
|
||||
|
||||
<!-- Upload Area -->
|
||||
<div
|
||||
@dragover="handleDragover"
|
||||
@dragleave="handleDragleave"
|
||||
@drop="handleDrop"
|
||||
:class="[
|
||||
'border-2 border-dashed rounded-lg p-8 text-center transition-colors cursor-pointer bg-base-200/50 mb-6',
|
||||
isDragover ? 'border-primary bg-primary/10' : 'border-base-300 hover:border-primary'
|
||||
]"
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
@change="handleFileUpload"
|
||||
class="hidden"
|
||||
id="file-upload"
|
||||
accept="video/*,image/*"
|
||||
/>
|
||||
<div @dragover="handleDragover" @dragleave="handleDragleave" @drop="handleDrop" :class="[
|
||||
'border-2 border-dashed rounded-lg p-8 text-center transition-colors cursor-pointer bg-base-200/50 mb-6',
|
||||
isDragover ? 'border-primary bg-primary/10' : 'border-base-300 hover:border-primary'
|
||||
]">
|
||||
<input type="file" multiple @change="handleFileUpload" class="hidden" id="file-upload"
|
||||
accept="video/*,image/*" />
|
||||
<label for="file-upload" class="cursor-pointer flex flex-col items-center gap-3">
|
||||
<i :class="['mdi text-4xl', isDragover ? 'mdi-cloud-check text-primary' : 'mdi-file-upload text-base-content/50']"></i>
|
||||
<i
|
||||
:class="['mdi text-4xl', isDragover ? 'mdi-cloud-check text-primary' : 'mdi-file-upload text-base-content/50']"></i>
|
||||
<div>
|
||||
<p class="font-semibold">Click to upload or drag and drop</p>
|
||||
<p class="text-sm text-base-content/70">Video or image files (MP4, PNG, etc.)</p>
|
||||
@@ -179,16 +194,14 @@ const goHome = () => {
|
||||
<div v-if="uploadedFiles.length > 0" class="mb-6">
|
||||
<p class="font-semibold mb-3">Selected Files:</p>
|
||||
<div class="space-y-2">
|
||||
<div v-for="(file, index) in uploadedFiles" :key="index" class="flex items-center gap-3 bg-base-200 p-3 rounded-lg">
|
||||
<div v-for="(file, index) in uploadedFiles" :key="index"
|
||||
class="flex items-center gap-3 bg-base-200 p-3 rounded-lg">
|
||||
<i class="mdi mdi-file text-primary"></i>
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="font-medium truncate">{{ file.name }}</p>
|
||||
<p class="text-xs text-base-content/70">{{ (file.size / 1024 / 1024).toFixed(2) }} MB</p>
|
||||
</div>
|
||||
<button
|
||||
@click="uploadedFiles.splice(index, 1)"
|
||||
class="btn btn-ghost btn-xs"
|
||||
>
|
||||
<button @click="uploadedFiles.splice(index, 1)" class="btn btn-ghost btn-xs">
|
||||
<i class="mdi mdi-close"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -201,11 +214,8 @@ const goHome = () => {
|
||||
<i class="mdi mdi-folder-open mr-2"></i>
|
||||
Choose Files
|
||||
</label>
|
||||
<button
|
||||
@click="submitRun"
|
||||
:disabled="uploadedFiles.length === 0 || isUploading"
|
||||
:class="['btn btn-primary flex-1', { 'loading': isUploading }]"
|
||||
>
|
||||
<button @click="submitRun" :disabled="uploadedFiles.length === 0 || isUploading"
|
||||
:class="['btn btn-primary flex-1', { 'loading': isUploading }]">
|
||||
<i v-if="!isUploading" class="mdi mdi-send mr-2"></i>
|
||||
{{ isUploading ? 'Submitting...' : 'Submit Run' }}
|
||||
</button>
|
||||
@@ -216,6 +226,44 @@ const goHome = () => {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Objectives Table -->
|
||||
<div class="card bg-base-100 shadow-lg mt-8">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-2xl mb-6">
|
||||
<i class="mdi mdi-view-list text-purple-500 mr-2"></i>
|
||||
Your Objectives
|
||||
</h2>
|
||||
|
||||
<div v-if="isLoadingObjectives" class="flex justify-center py-8">
|
||||
<span class="loading loading-spinner loading-lg"></span>
|
||||
</div>
|
||||
|
||||
<div v-else-if="objectives.length === 0" class="text-center py-8">
|
||||
<p class="text-base-content/70 mb-2">No objectives completed yet</p>
|
||||
<p class="text-sm text-base-content/50">Submit your runs to unlock objectives!</p>
|
||||
</div>
|
||||
|
||||
<div v-else class="overflow-x-auto">
|
||||
<table class="table table-zebra w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Objective ID</th>
|
||||
<th class="text-right">Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="obj in objectives" :key="obj.objectiv_id">
|
||||
<td class="font-medium">{{ obj.objectiv_id }}</td>
|
||||
<td class="text-right">
|
||||
<span class="badge badge-primary badge-lg">{{ obj.count }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user