authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-11 10:09:48-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-11 10:09:48-07:00
log05d404210058d714cfef902517fc20ad66b82339
treebd998c99ca7002a2463b4f3fe9721037b79cc17c
parent2ebc9fa4ed24e389eef24039f27c73ae6633858f
signature Signed by PGP key B5690EEEBB952194

feat(web): open Usage on the Limits tab by default (#11261)

Co-authored-by: Claude Code <noreply@anthropic.com>

3 files changed, 13 insertions(+), 11 deletions(-)

apps/mobile/src/features/usage/UsageRouteScreen.tsx+3-1
...@@ -67,7 +67,9 @@ const CHART_HEIGHT = 180;...@@ -67,7 +67,9 @@ const CHART_HEIGHT = 180;
67export function UsageRouteScreen() {67export function UsageRouteScreen() {
68 const navigation = useNavigation();68 const navigation = useNavigation();
69 const insets = useSafeAreaInsets();69 const insets = useSafeAreaInsets();
70 const [tab, setTab] = useState<UsageTab>("usage");70 // Limits first: remaining quota and reset time are what most people open
71 // the screen for.
72 const [tab, setTab] = useState<UsageTab>("limits");
71 const [windowSelection, setWindowSelection] = useState(() => ({73 const [windowSelection, setWindowSelection] = useState(() => ({
72 days: 30,74 days: 30,
73 window: makeWindow(30),75 window: makeWindow(30),
apps/web/src/components/usage/usagePagePreferences.test.ts+3-3
...@@ -25,7 +25,7 @@ afterEach(() => {...@@ -25,7 +25,7 @@ afterEach(() => {
2525
26describe("Usage page preferences", () => {26describe("Usage page preferences", () => {
27 it("uses defaults when no preference has been saved", () => {27 it("uses defaults when no preference has been saved", () => {
28 expect(readUsagePagePreferences()).toEqual({ metric: "cost", windowDays: 30 });28 expect(readUsagePagePreferences()).toEqual({ metric: "limits", windowDays: 30 });
29 });29 });
3030
31 it.each([1, 7, 30, 90] as const)("round-trips every metric with a %i-day range", (windowDays) => {31 it.each([1, 7, 30, 90] as const)("round-trips every metric with a %i-day range", (windowDays) => {
...@@ -41,7 +41,7 @@ describe("Usage page preferences", () => {...@@ -41,7 +41,7 @@ describe("Usage page preferences", () => {
41 '{"metric":"cost","windowDays":365}',41 '{"metric":"cost","windowDays":365}',
42 ])("replaces invalid preferences on the next save: %s", (value) => {42 ])("replaces invalid preferences on the next save: %s", (value) => {
43 values.set(key, value);43 values.set(key, value);
44 expect(readUsagePagePreferences()).toEqual({ metric: "cost", windowDays: 30 });44 expect(readUsagePagePreferences()).toEqual({ metric: "limits", windowDays: 30 });
45 saveUsagePagePreferences({ metric: "tokens", windowDays: 7 });45 saveUsagePagePreferences({ metric: "tokens", windowDays: 7 });
46 expect(readUsagePagePreferences()).toEqual({ metric: "tokens", windowDays: 7 });46 expect(readUsagePagePreferences()).toEqual({ metric: "tokens", windowDays: 7 });
47 });47 });
...@@ -64,7 +64,7 @@ describe("Usage page preferences", () => {...@@ -64,7 +64,7 @@ describe("Usage page preferences", () => {
64 throw new Error("SecurityError");64 throw new Error("SecurityError");
65 },65 },
66 });66 });
67 expect(readUsagePagePreferences()).toEqual({ metric: "cost", windowDays: 30 });67 expect(readUsagePagePreferences()).toEqual({ metric: "limits", windowDays: 30 });
68 expect(() => saveUsagePagePreferences({ metric: "tokens", windowDays: 7 })).not.toThrow();68 expect(() => saveUsagePagePreferences({ metric: "tokens", windowDays: 7 })).not.toThrow();
69 });69 });
70});70});
apps/web/src/components/usage/usagePagePreferences.ts+7-7
...@@ -9,17 +9,17 @@ const UsagePagePreferencesSchema = Schema.Struct({...@@ -9,17 +9,17 @@ const UsagePagePreferencesSchema = Schema.Struct({
9});9});
10export type UsagePagePreferences = typeof UsagePagePreferencesSchema.Type;10export type UsagePagePreferences = typeof UsagePagePreferencesSchema.Type;
1111
12// Limits is what most people open the page for (how much subscription quota is
13// left, and when it resets), so it is the first-visit default; the last picked
14// tab sticks after that.
15const DEFAULT_PREFERENCES: UsagePagePreferences = { metric: "limits", windowDays: 30 };
16
12export function readUsagePagePreferences(): UsagePagePreferences {17export function readUsagePagePreferences(): UsagePagePreferences {
13 try {18 try {
14 return (19 return getLocalStorageItem(STORAGE_KEY, UsagePagePreferencesSchema) ?? DEFAULT_PREFERENCES;
15 getLocalStorageItem(STORAGE_KEY, UsagePagePreferencesSchema) ?? {
16 metric: "cost",
17 windowDays: 30,
18 }
19 );
20 } catch (error) {20 } catch (error) {
21 console.error("Could not read Usage page preferences.", error);21 console.error("Could not read Usage page preferences.", error);
22 return { metric: "cost", windowDays: 30 };22 return DEFAULT_PREFERENCES;
23 }23 }
24}24}
2525