iota-frontend/src/hooks/use-users.ts
2026-04-02 22:39:50 +02:00

115 lines
2.9 KiB
TypeScript

import useSWR from "swr";
// API response interface (what we receive from the server)
type ApiUserResponse = {
uuid: string;
username: string;
displayname?: string;
public_key: string;
private_key_hash: string;
avatar?: string;
storage: number;
connected: boolean;
createdAt: number;
};
// User interface (what we use in the UI - includes computed displayName)
interface User extends ApiUserResponse {
displayName: string; // Always provided by our processing
}
// SWR fetcher function
const fetcher = (url: string) => fetch(url).then((res) => res.json());
// Custom hook for checking username availability
export const useUsernameAvailability = (username: string) => {
const shouldFetch = username && username.length >= 3;
const { data, error, isLoading } = useSWR(
shouldFetch ? `https://omega.tensamin.net/api/get/id/${username}` : null,
fetcher,
{
revalidateOnFocus: false,
dedupingInterval: 5000, // Cache for 5 seconds
},
);
return {
isAvailable: data?.type === "error", // "error" means username is available
isTaken: data?.type === "success", // "success" means username is taken
isLoading,
error,
};
};
// Custom hook for getting users list
export const useUsers = () => {
const {
data,
error,
isLoading,
mutate: refreshUsers,
} = useSWR("/api/users/get/", fetcher, {
revalidateOnFocus: false,
dedupingInterval: 30000, // Cache for 30 seconds
});
// Process the API response to ensure UI compatibility
// Check if data is an array before processing
const processedUsers = (Array.isArray(data) ? data : []).map(
(user: ApiUserResponse) => ({
...user,
displayName: user.displayname || user.username, // Always provide displayName for UI
}),
) as User[];
// Wrapper function that only resolves if refresh succeeds
const refreshUsersWithPromise = async () => {
try {
const result = await refreshUsers();
// Check if the result is valid (array of users)
if (!Array.isArray(result)) {
throw new Error("Failed to load users");
}
return result;
} catch (error) {
throw error;
}
};
// Function to delete a user
const deleteUser = async (uuid: string) => {
try {
const response = await fetch("/api/users/remove/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ uuid }),
});
if (!response.ok) {
throw new Error("Failed to delete user");
}
const result = await response.json();
// Refresh the users list after successful deletion
await refreshUsersWithPromise();
return result;
} catch (error) {
throw error;
}
};
return {
users: processedUsers,
isLoading,
error,
refreshUsers: refreshUsersWithPromise,
deleteUser,
};
};
// Export User type for other components to use
export type { User };