mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-15 22:21:20 +00:00
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:
@@ -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 });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user