refactor(usage): extract useQuotaVisibility hook (file-size budget)

ProviderLimits/index.tsx grew past its frozen 1127-line budget with the
quota-visibility wiring; extract the state + persistence + hide/show handlers
into a dedicated hook (same pattern as useCodexResetCreditRedemption).
No behavior change — the live validation evidence on the PR covers this flow
end-to-end.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
diegosouzapw
2026-07-16 18:19:05 -03:00
committed by Diego Rodrigues de Sa e Souza
parent 5cc604c05a
commit 39b4fc38a4
2 changed files with 91 additions and 77 deletions

View File

@@ -12,7 +12,6 @@ import {
calculatePercentage,
matchesProviderFilter,
buildProviderOptions,
getQuotaVisibilityKey,
} from "./utils";
import Card from "@/shared/components/Card";
import { CardSkeleton } from "@/shared/components/Loading";
@@ -20,6 +19,8 @@ import { USAGE_SUPPORTED_PROVIDERS } from "@/shared/constants/providers";
import { pickDisplayValue } from "@/shared/utils/maskEmail";
import useEmailPrivacyStore from "@/store/emailPrivacyStore";
import { useNotificationStore } from "@/store/notificationStore";
import { useQuotaVisibility } from "./useQuotaVisibility";
import QuotaCutoffModal from "./QuotaCutoffModal";
import QuotaCardGrid from "./QuotaCardGrid";
import { useVisibleQuotaData } from "./useVisibleQuotaData";
@@ -200,12 +201,7 @@ export default function ProviderLimits({
const [refreshingAll, setRefreshingAll] = useState(false);
const [initialLoading, setInitialLoading] = useState(true);
const [tierFilter, setTierFilter] = useState("all");
// Per-operator quota row visibility (upstream 9router#2371 port). Keyed by
// provider id → { hidden: [<quota visibility key>] }, persisted server-side
// via PATCH /api/settings so it survives refresh/reload.
const [quotaVisibility, setQuotaVisibility] = useState<Record<string, { hidden?: string[] }>>(
{}
);
const { quotaVisibility, handleHideQuota, handleShowQuota } = useQuotaVisibility(tr, notify);
const resetCreditRedemption = useCodexResetCreditRedemption(
tr,
setErrors,
@@ -328,76 +324,6 @@ export default function ProviderLimits({
[notify, tr]
);
// Load persisted per-operator quota row visibility once on mount. Best
// effort — a fetch failure just leaves every row visible (safe default).
useEffect(() => {
let alive = true;
fetch("/api/settings", { cache: "no-store" })
.then((r) => (r.ok ? r.json() : {}))
.then((s) => {
if (alive) setQuotaVisibility(s?.quotaVisibility || {});
})
.catch(() => {});
return () => {
alive = false;
};
}, []);
const persistQuotaVisibility = useCallback(
async (
next: Record<string, { hidden?: string[] }>,
previous: Record<string, { hidden?: string[] }>
) => {
setQuotaVisibility(next);
try {
const response = await fetch("/api/settings", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ quotaVisibility: next }),
});
if (!response.ok) throw new Error("Failed to update quota visibility");
} catch {
setQuotaVisibility(previous);
notify.error(tr("quotaVisibilityUpdateFailed", "Failed to update quota visibility"));
}
},
[notify, tr]
);
const handleHideQuota = useCallback(
(provider: string, quotaRow: any) => {
const key = getQuotaVisibilityKey(quotaRow);
if (!provider || !key) return;
const previous = quotaVisibility;
const providerVisibility = previous[provider] || {};
const hidden = new Set(providerVisibility.hidden || []);
hidden.add(key);
const next = {
...previous,
[provider]: { ...providerVisibility, hidden: [...hidden] },
};
persistQuotaVisibility(next, previous);
},
[quotaVisibility, persistQuotaVisibility]
);
const handleShowQuota = useCallback(
(provider: string, quotaRow: any) => {
const key = getQuotaVisibilityKey(quotaRow);
if (!provider || !key) return;
const previous = quotaVisibility;
const providerVisibility = previous[provider] || {};
const hidden = new Set(providerVisibility.hidden || []);
hidden.delete(key);
const next = {
...previous,
[provider]: { ...providerVisibility, hidden: [...hidden] },
};
persistQuotaVisibility(next, previous);
},
[quotaVisibility, persistQuotaVisibility]
);
const applyCachedQuotaState = useCallback(
(connectionList: any[], caches: Record<string, any>) => {
const nextQuotaData: Record<string, any> = {};

View File

@@ -0,0 +1,88 @@
"use client";
import { useCallback, useEffect, useState } from "react";
import { getQuotaVisibilityKey } from "./utils";
type QuotaVisibilityMap = Record<string, { hidden?: string[] }>;
type Translate = (key: string, fallback: string) => string;
interface NotifyLike {
error: (message: string) => void;
}
/**
* Per-operator quota row visibility (upstream 9router#2371 port). Keyed by
* provider id → { hidden: [<quota visibility key>] }, persisted server-side
* via PATCH /api/settings so it survives refresh/reload.
*
* Extracted from ProviderLimits/index.tsx to keep the container under the
* frozen file-size budget — same pattern as useCodexResetCreditRedemption.
*/
export function useQuotaVisibility(tr: Translate, notify: NotifyLike) {
const [quotaVisibility, setQuotaVisibility] = useState<QuotaVisibilityMap>({});
// Load persisted per-operator quota row visibility once on mount. Best
// effort — a fetch failure just leaves every row visible (safe default).
useEffect(() => {
let alive = true;
fetch("/api/settings", { cache: "no-store" })
.then((r) => (r.ok ? r.json() : {}))
.then((s) => {
if (alive) setQuotaVisibility(s?.quotaVisibility || {});
})
.catch(() => {});
return () => {
alive = false;
};
}, []);
const persistQuotaVisibility = useCallback(
async (next: QuotaVisibilityMap, previous: QuotaVisibilityMap) => {
setQuotaVisibility(next);
try {
const response = await fetch("/api/settings", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ quotaVisibility: next }),
});
if (!response.ok) throw new Error("Failed to update quota visibility");
} catch {
setQuotaVisibility(previous);
notify.error(tr("quotaVisibilityUpdateFailed", "Failed to update quota visibility"));
}
},
[notify, tr]
);
const toggleQuotaKey = useCallback(
(provider: string, quotaRow: any, hide: boolean) => {
const key = getQuotaVisibilityKey(quotaRow);
if (!provider || !key) return;
const previous = quotaVisibility;
const providerVisibility = previous[provider] || {};
const hidden = new Set(providerVisibility.hidden || []);
if (hide) hidden.add(key);
else hidden.delete(key);
const next = {
...previous,
[provider]: { ...providerVisibility, hidden: [...hidden] },
};
persistQuotaVisibility(next, previous);
},
[quotaVisibility, persistQuotaVisibility]
);
const handleHideQuota = useCallback(
(provider: string, quotaRow: any) => toggleQuotaKey(provider, quotaRow, true),
[toggleQuotaKey]
);
const handleShowQuota = useCallback(
(provider: string, quotaRow: any) => toggleQuotaKey(provider, quotaRow, false),
[toggleQuotaKey]
);
return { quotaVisibility, handleHideQuota, handleShowQuota };
}