feat(ui): persist provider selection in cliproxy and auth-monitor

- save selected provider to localStorage on both pages
- restore selection on page load
- validate saved provider still exists before restoring
- improves UX by eliminating need to re-select provider after reload
This commit is contained in:
kaitranntt
2026-01-25 17:34:55 -05:00
parent e3920e0776
commit 7fc9ff0d77
2 changed files with 59 additions and 11 deletions
@@ -4,7 +4,7 @@
* Uses glass panel aesthetic with hover interactions and glow effects
*/
import { useState } from 'react';
import { useState, useMemo } from 'react';
import { STATUS_COLORS } from '@/lib/utils';
import { Skeleton } from '@/components/ui/skeleton';
import { AccountFlowViz } from '@/components/account-flow-viz';
@@ -17,6 +17,8 @@ import { LivePulse } from './components/live-pulse';
import { ProviderCard } from './components/provider-card';
import { SummaryCard } from './components/summary-card';
const STORAGE_KEY = 'auth-monitor-selected-provider';
export function AuthMonitor() {
const {
accounts,
@@ -31,7 +33,32 @@ export function AuthMonitor() {
} = useAuthMonitorData();
const { privacyMode } = usePrivacy();
const [selectedProvider, setSelectedProvider] = useState<string | null>(null);
// Persist selected provider in localStorage
const [selectedProvider, setSelectedProviderState] = useState<string | null>(() => {
if (typeof window !== 'undefined') {
return localStorage.getItem(STORAGE_KEY);
}
return null;
});
// Wrapper to persist selection
const setSelectedProvider = (provider: string | null) => {
setSelectedProviderState(provider);
if (provider) {
localStorage.setItem(STORAGE_KEY, provider);
} else {
localStorage.removeItem(STORAGE_KEY);
}
};
// Effective provider: prefer saved (if still exists) > null (show grid)
const effectiveProvider = useMemo(() => {
if (selectedProvider && providerStats.some((p) => p.provider === selectedProvider)) {
return selectedProvider;
}
return null;
}, [selectedProvider, providerStats]);
const [hoveredProvider, setHoveredProvider] = useState<string | null>(null);
// Account control mutations for flow viz
@@ -39,16 +66,16 @@ export function AuthMonitor() {
const resumeMutation = useResumeAccount();
// Get selected provider data for detail view
const selectedProviderData = selectedProvider
? providerStats.find((ps) => ps.provider === selectedProvider)
const selectedProviderData = effectiveProvider
? providerStats.find((ps) => ps.provider === effectiveProvider)
: null;
const handlePauseToggle = (accountId: string, paused: boolean) => {
if (!selectedProvider || pauseMutation.isPending || resumeMutation.isPending) return;
if (!effectiveProvider || pauseMutation.isPending || resumeMutation.isPending) return;
if (paused) {
pauseMutation.mutate({ provider: selectedProvider, accountId });
pauseMutation.mutate({ provider: effectiveProvider, accountId });
} else {
resumeMutation.mutate({ provider: selectedProvider, accountId });
resumeMutation.mutate({ provider: effectiveProvider, accountId });
}
};
+25 -4
View File
@@ -194,7 +194,13 @@ export function CliproxyPage() {
const deleteMutation = useDeleteVariant();
// Selection state: either a provider or a variant
const [selectedProvider, setSelectedProvider] = useState<string | null>(null);
// Initialize from localStorage if available
const [selectedProvider, setSelectedProviderState] = useState<string | null>(() => {
if (typeof window !== 'undefined') {
return localStorage.getItem('cliproxy-selected-provider');
}
return null;
});
const [selectedVariant, setSelectedVariant] = useState<string | null>(null);
const [wizardOpen, setWizardOpen] = useState(false);
const [addAccountProvider, setAddAccountProvider] = useState<{
@@ -207,14 +213,29 @@ export function CliproxyPage() {
const isRemoteMode = authData?.source === 'remote';
const variants = useMemo(() => variantsData?.variants || [], [variantsData?.variants]);
// Auto-select first provider if nothing selected
// Wrapper to persist provider selection to localStorage
const setSelectedProvider = (provider: string | null) => {
setSelectedProviderState(provider);
if (provider) {
localStorage.setItem('cliproxy-selected-provider', provider);
}
};
// Effective provider: prefer saved > first with accounts > first
const effectiveProvider = useMemo(() => {
// If a variant is selected, no provider is effective
if (selectedVariant) return null;
// If saved/selected provider is valid, use it
if (selectedProvider && providers.some((p) => p.provider === selectedProvider)) {
return selectedProvider;
}
return providers.length > 0 ? providers[0].provider : null;
// Auto-select: prefer first provider with accounts (better UX)
if (providers.length > 0) {
const providerWithAccounts = providers.find((p) => (p.accounts?.length || 0) > 0);
return providerWithAccounts?.provider || providers[0]?.provider || null;
}
return null;
}, [selectedProvider, selectedVariant, providers]);
const selectedStatus = providers.find((p) => p.provider === effectiveProvider);