Add page to allow admins to inspect all of the details stored on the server of a user account. For now this is just the UserDetails, but in the future this is planned to be expanded to also show sessions and logs.
93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
/*
|
|
SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
|
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
import { Info } from "~/shared/utils/luxon";
|
|
import { defineStore } from 'pinia'
|
|
|
|
interface SyncOperation {
|
|
controller: AbortController,
|
|
promise: Promise<Ref<ClientMap<ClientUser>>>,
|
|
}
|
|
|
|
export const useUsersStore = defineStore("users", () => {
|
|
const accountStore = useAccountStore();
|
|
|
|
const state = {
|
|
fetched: ref<boolean>(false),
|
|
pendingSync: ref<SyncOperation>(),
|
|
users: ref<ClientMap<ClientUser>>(new ClientMap(ClientUser, new Map(), new Map())),
|
|
}
|
|
const getters = {
|
|
}
|
|
const actions = {
|
|
async fetch() {
|
|
if (!accountStore.isCrew || state.fetched.value) {
|
|
return state.users;
|
|
}
|
|
const pending = state.pendingSync.value;
|
|
if (pending) {
|
|
return pending.promise;
|
|
}
|
|
|
|
const requestFetch = useRequestFetch();
|
|
const controller = new AbortController();
|
|
const zone = Info.normalizeZone(accountStore.activeTimezone);
|
|
const locale = accountStore.activeLocale;
|
|
const promise = (async () => {
|
|
try {
|
|
const apiUsers = await requestFetch("/api/users", { signal: controller.signal });
|
|
state.users.value.apiUpdate(apiUsers, { zone, locale });
|
|
state.pendingSync.value = undefined;
|
|
state.fetched.value = true;
|
|
return state.users;
|
|
} catch (err: any) {
|
|
if (err.name !== "AbortError")
|
|
state.pendingSync.value = undefined;
|
|
throw err;
|
|
}
|
|
})();
|
|
state.pendingSync.value = {
|
|
controller,
|
|
promise,
|
|
};
|
|
return promise;
|
|
},
|
|
async resync(id: number) {
|
|
const pending = state.pendingSync.value;
|
|
if (pending) {
|
|
pending.controller.abort();
|
|
}
|
|
state.pendingSync.value = undefined;
|
|
state.fetched.value = false;
|
|
await actions.fetch();
|
|
},
|
|
async saveUser(user: ClientUser) {
|
|
try {
|
|
await $fetch("/api/admin/user", {
|
|
method: "PATCH",
|
|
body: user.toApi(),
|
|
});
|
|
} catch (err: any) {
|
|
console.error(err);
|
|
alert(err?.data?.message ?? err.message);
|
|
}
|
|
},
|
|
}
|
|
|
|
appEventSource?.addEventListener("update", (event) => {
|
|
if (event.data.type !== "user-update") {
|
|
return;
|
|
}
|
|
console.log("appyling", event.data)
|
|
const zone = Info.normalizeZone(accountStore.activeTimezone);
|
|
const locale = accountStore.activeLocale;
|
|
state.users.value.apiUpdate([event.data.data], { zone, locale });
|
|
});
|
|
|
|
return {
|
|
...state,
|
|
...getters,
|
|
...actions,
|
|
};
|
|
})
|