feat(noita): stores

This commit is contained in:
2026-05-24 09:29:30 +02:00
parent 9fd0122a67
commit 821e453bc0
13 changed files with 240 additions and 176 deletions
+8 -130
View File
@@ -1,7 +1,9 @@
<script setup lang="ts">
import { ref, computed, onMounted } from "vue";
import { storeToRefs } from "pinia";
import dayjs from "dayjs";
import RankBadge from "@/components/RankBadge.vue";
import { useNoitaStore, type Objective } from "@/stores/noita";
import {
createColumnHelper,
useVueTable,
@@ -12,32 +14,11 @@ import {
type SortingState,
} from "@tanstack/vue-table";
interface Objective {
objectiv_id: string;
display_string: string;
first_seen_at: string | null;
count: number;
max_count: number;
seed: string | null;
points_per_objectiv: number;
total_points: number;
}
const userInfo = ref({
username: "Player",
rank: null as number | null,
score: 0,
runsSubmitted: 0,
deathsCount: 0,
isStaff: false,
});
const noitaStore = useNoitaStore();
const { userInfo, objectives, leaderboard, isLoadingLeaderboard, isUploading } = storeToRefs(noitaStore);
const uploadedFiles = ref<File[]>([]);
const isUploading = ref(false);
const isDragover = ref(false);
const objectives = ref<Objective[]>([]);
const isLoadingLeaderboard = ref(false);
const leaderboard = ref<any[]>([]);
const columnHelper = createColumnHelper<Objective>();
const sorting = ref<SortingState>([]);
@@ -153,40 +134,13 @@ const handleDrop = (event: DragEvent) => {
const submitRun = async () => {
if (uploadedFiles.value.length === 0) return;
isUploading.value = true;
try {
for (const file of uploadedFiles.value) {
const formData = new FormData();
formData.append("file", file);
const response = await fetch("/api/noita/submit", {
method: "POST",
body: formData,
});
if (!response.ok) {
const error = await response.json();
alert(`Error submitting ${file.name}: ${error.detail || "Unknown error"}`);
return;
}
const result = await response.json();
console.log("Submission successful:", result);
}
await noitaStore.submitRun(uploadedFiles.value);
uploadedFiles.value = [];
alert("Run submitted successfully!");
// Refresh objectives, score, and rank after successful submission
await Promise.all([
fetchUserResults(),
fetchLeaderboard(),
]);
} catch (error) {
console.error("Error submitting run:", error);
alert("Error submitting run. Please try again.");
} finally {
isUploading.value = false;
}
};
@@ -194,94 +148,18 @@ const goHome = () => {
window.location.href = "/";
};
const fetchUserResults = async () => {
try {
const response = await fetch("/api/noita/results");
if (!response.ok) throw new Error("Failed to fetch results");
const results = await response.json();
userInfo.value.score = results.total_score;
userInfo.value.deathsCount = results.deaths_count;
userInfo.value.runsSubmitted = results.objectives.length;
objectives.value = results.objectives;
} catch (error) {
console.error("Error fetching results:", error);
}
};
const fetchLeaderboard = async () => {
isLoadingLeaderboard.value = true;
try {
const response = await fetch("/api/noita/leaderboard");
if (!response.ok) throw new Error("Failed to fetch leaderboard");
const data = await response.json();
leaderboard.value = data.leaderboard;
// Find current user's rank
const userRank = leaderboard.value.find(
(entry: any) => entry.username === userInfo.value.username
);
if (userRank) {
userInfo.value.rank = userRank.rank;
userInfo.value.score = userRank.total_score;
userInfo.value.deathsCount = userRank.deaths_count;
}
} catch (error) {
console.error("Error fetching leaderboard:", error);
} finally {
isLoadingLeaderboard.value = false;
}
};
const clearCache = async () => {
try {
const response = await fetch("/api/cache/clear", {
method: "POST",
});
if (response.ok) {
alert("Cache cleared successfully!");
// Refresh data after clearing cache
await Promise.all([
fetchUserResults(),
fetchLeaderboard(),
]);
} else {
const error = await response.json();
alert(`Error clearing cache: ${error.detail || "Unknown error"}`);
}
await noitaStore.clearCache();
alert("Cache cleared successfully!");
} catch (error) {
console.error("Error clearing cache:", error);
alert("Error clearing cache. Please try again.");
}
};
const loadUserData = async () => {
// Get user info first
try {
const response = await fetch("/api/user");
if (response.ok) {
const user = await response.json();
if (user.is_authenticated) {
userInfo.value.username = user.username;
userInfo.value.isStaff = user.is_staff || false;
}
}
} catch (error) {
console.error("Error fetching user info:", error);
}
// Fetch results and leaderboard
await Promise.all([
fetchUserResults(),
fetchLeaderboard(),
]);
};
onMounted(() => {
loadUserData();
noitaStore.loadUserData();
});
</script>