Files
Jyotisha/frontend/src/lib/settings-url.ts
T
Jesse_ChenandCursor dc6598d7e4 fix(web): keep the settings dialog one size and move billing into it (BUG-554)
The four account panes now share a fixed frame, chart profiles open as list then detail, and membership lives in the homepage dialog instead of a separate page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 18:29:51 +08:00

41 lines
1.4 KiB
TypeScript

import type { BillingPaneTab, MembershipPlanAlias } from "@/lib/membership";
export const SETTINGS_QUERY_KEY = "settings";
export type SettingsQuery = {
readonly pane: "billing";
readonly source: string | null;
readonly plan: MembershipPlanAlias | null;
readonly tab: BillingPaneTab | null;
};
const PLAN_ALIASES: ReadonlySet<string> = new Set(["trial", "monthly", "yearly"]);
const BILLING_TABS: ReadonlySet<string> = new Set(["membership", "credits", "redeem", "orders"]);
function searchParams(search: string) {
return new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
}
export function parseSettingsQuery(search: string): SettingsQuery | null {
const params = searchParams(search);
if (params.get(SETTINGS_QUERY_KEY) !== "billing") return null;
const planRaw = params.get("plan");
const tabRaw = params.get("tab");
return {
pane: "billing",
source: params.get("source"),
plan: planRaw && PLAN_ALIASES.has(planRaw) ? planRaw as MembershipPlanAlias : null,
tab: tabRaw && BILLING_TABS.has(tabRaw) ? tabRaw as BillingPaneTab : null,
};
}
export function stripSettingsQuery(search: string, pathname = "/") {
const params = searchParams(search);
params.delete(SETTINGS_QUERY_KEY);
params.delete("source");
params.delete("plan");
params.delete("tab");
const query = params.toString();
return query ? `${pathname}?${query}` : pathname || "/";
}