82 lines
2.8 KiB
TypeScript
82 lines
2.8 KiB
TypeScript
import { create } from "zustand";
|
|
import { requestOnlineJson } from "./onlineAccountClient";
|
|
import type { PlayerSession } from "./types";
|
|
import type { RandomizedBiteSizedCreature, RandomizedCreatureKind } from "../game/dungeons/randomizedBiteSizedStockades";
|
|
|
|
export const CREATURE_READINESS_STATUSES = ["ready", "needs-testing", "not-ready"] as const;
|
|
export type CreatureReadinessStatus = (typeof CREATURE_READINESS_STATUSES)[number];
|
|
|
|
export const CREATURE_READINESS_LABELS: Readonly<Record<CreatureReadinessStatus, string>> = {
|
|
ready: "Ready",
|
|
"needs-testing": "Needs Tested",
|
|
"not-ready": "Not Ready",
|
|
};
|
|
|
|
export interface RandomizedCreatureReview {
|
|
readonly creatureKey: string;
|
|
readonly dungeonId: string;
|
|
readonly creatureName: string;
|
|
readonly creatureKind: RandomizedCreatureKind;
|
|
readonly status: CreatureReadinessStatus;
|
|
readonly reviewedBy: string;
|
|
readonly reviewedAt: number;
|
|
}
|
|
|
|
interface RandomizedCreatureReadinessState {
|
|
readonly reviews: Readonly<Record<string, RandomizedCreatureReview>>;
|
|
readonly loading: boolean;
|
|
readonly error: string;
|
|
refresh: () => Promise<void>;
|
|
save: (
|
|
session: PlayerSession,
|
|
creature: RandomizedBiteSizedCreature,
|
|
status: CreatureReadinessStatus,
|
|
) => Promise<boolean>;
|
|
}
|
|
|
|
export const useRandomizedCreatureReadiness = create<RandomizedCreatureReadinessState>((set, get) => ({
|
|
reviews: {},
|
|
loading: false,
|
|
error: "",
|
|
refresh: async () => {
|
|
set({ loading: true, error: "" });
|
|
try {
|
|
const payload = await requestOnlineJson<{ reviews: RandomizedCreatureReview[] }>(
|
|
"/api/randomized-creature-readiness",
|
|
);
|
|
set({ reviews: Object.fromEntries(payload.reviews.map((review) => [review.creatureKey, review])) });
|
|
} catch (error) {
|
|
set({ error: error instanceof Error ? error.message : "Unable to load creature readiness." });
|
|
} finally {
|
|
set({ loading: false });
|
|
}
|
|
},
|
|
save: async (session, creature, status) => {
|
|
if (session.kind !== "account" || !session.accessToken) return false;
|
|
set({ loading: true, error: "" });
|
|
try {
|
|
const payload = await requestOnlineJson<{ review: RandomizedCreatureReview }>(
|
|
"/api/gm/randomized-creature-readiness",
|
|
{
|
|
method: "PUT",
|
|
body: JSON.stringify({
|
|
creatureKey: creature.key,
|
|
dungeonId: "randomized-bite-sized-stormwind-stockade",
|
|
creatureName: creature.name,
|
|
creatureKind: creature.kind,
|
|
status,
|
|
}),
|
|
},
|
|
session.accessToken,
|
|
);
|
|
set({ reviews: { ...get().reviews, [payload.review.creatureKey]: payload.review } });
|
|
return true;
|
|
} catch (error) {
|
|
set({ error: error instanceof Error ? error.message : "Unable to save creature readiness." });
|
|
return false;
|
|
} finally {
|
|
set({ loading: false });
|
|
}
|
|
},
|
|
}));
|