83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
import { useState, useCallback, useEffect } from "react";
|
|
import { fetchClaudeOrgs, fetchClaudeUsage } from "@/lib/api/claudeApi";
|
|
import {
|
|
loadClaudeSessionKey,
|
|
saveClaudeSessionKey,
|
|
clearClaudeSessionKey,
|
|
} from "@/lib/storage";
|
|
import type { ClaudeUsageResponse } from "@/types/claude";
|
|
|
|
type Status = "idle" | "loading" | "success" | "error";
|
|
|
|
export function useClaudeUsage() {
|
|
const [sessionKey, setSessionKey] = useState<string | null>(null);
|
|
const [pendingKey, setPendingKey] = useState("");
|
|
const [usage, setUsage] = useState<ClaudeUsageResponse | null>(null);
|
|
const [status, setStatus] = useState<Status>("idle");
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
loadClaudeSessionKey().then((stored) => {
|
|
if (stored) setSessionKey(stored);
|
|
});
|
|
}, []);
|
|
|
|
const saveKey = useCallback(async () => {
|
|
const trimmed = pendingKey.trim();
|
|
if (!trimmed.startsWith("sk-ant-")) {
|
|
setError("Session key must start with sk-ant-");
|
|
return;
|
|
}
|
|
await saveClaudeSessionKey(trimmed);
|
|
setSessionKey(trimmed);
|
|
setPendingKey("");
|
|
setError(null);
|
|
}, [pendingKey]);
|
|
|
|
const refresh = useCallback(async () => {
|
|
if (!sessionKey) return;
|
|
setStatus("loading");
|
|
setError(null);
|
|
try {
|
|
const orgs = await fetchClaudeOrgs(sessionKey);
|
|
if (!orgs.length) throw new Error("NO_ORGS_FOUND");
|
|
const orgUuid = orgs[0].uuid;
|
|
const data = await fetchClaudeUsage(sessionKey, orgUuid);
|
|
setUsage(data);
|
|
setStatus("success");
|
|
} catch (e: unknown) {
|
|
const msg = e instanceof Error ? e.message : "UNKNOWN_ERROR";
|
|
setError(msg);
|
|
setStatus("error");
|
|
if (msg === "TOKEN_EXPIRED") {
|
|
await clearClaudeSessionKey();
|
|
setSessionKey(null);
|
|
}
|
|
}
|
|
}, [sessionKey]);
|
|
|
|
useEffect(() => {
|
|
if (sessionKey) void refresh();
|
|
}, [sessionKey]);
|
|
|
|
const clearKey = useCallback(async () => {
|
|
await clearClaudeSessionKey();
|
|
setSessionKey(null);
|
|
setUsage(null);
|
|
setStatus("idle");
|
|
setError(null);
|
|
}, []);
|
|
|
|
return {
|
|
sessionKey,
|
|
pendingKey,
|
|
setPendingKey,
|
|
usage,
|
|
status,
|
|
error,
|
|
saveKey,
|
|
refresh,
|
|
clearKey,
|
|
};
|
|
}
|