import { useEffect, useRef, useState } from 'react'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation, useQuery, useQueryClient, } from '@tanstack/react-query'; import type { AuthResponse, CompleteCodexManualLoginInput, LoginInput, RegisterInput, StartCodexLoginInput, } from '@codexdash/shared-types'; import { Activity, CirclePlus, ExternalLink, Gauge, Link as LinkIcon, LoaderCircle, LogOut, RefreshCw, ShieldCheck, Trash2, Waypoints, } from 'lucide-react'; import { toast, Toaster } from 'sonner'; import { api } from '@/lib/api'; import { clearToken, getToken, setToken } from '@/lib/storage'; import { extractUsageWindows, formatDate, formatDurationSeconds, getFastestResetAt, getUsageProgressTone, summarizeUsageWindows, } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Badge } from '@/components/ui/badge'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { Progress } from '@/components/ui/progress'; import { Separator } from '@/components/ui/separator'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; const registerSchema = z.object({ name: z.string().min(2), email: z.email(), password: z.string().min(8), }); const loginSchema = z.object({ email: z.email(), password: z.string().min(8), }); const connectSchema = z.object({ label: z.string().min(2), emailHint: z.string().optional(), }); const manualCallbackSchema = z.object({ callbackUrl: z.string().min(10), }); function AuthShell({ onAuthenticated, }: { onAuthenticated: (response: AuthResponse) => void; }) { const [mode, setMode] = useState<'login' | 'register'>('register'); const schema = mode === 'register' ? registerSchema : loginSchema; const form = useForm<{ name?: string; email: string; password: string }>({ resolver: zodResolver(schema), defaultValues: { email: '', password: '', ...(mode === 'register' ? { name: '' } : {}), }, }); const mutation = useMutation({ mutationFn: async (values: { name?: string; email: string; password: string; }) => { return mode === 'register' ? api.register(values as RegisterInput) : api.login({ email: values.email, password: values.password, } as LoginInput); }, onSuccess: (response) => { setToken(response.token); onAuthenticated(response); toast.success( mode === 'register' ? 'Welcome to CodexDash.' : 'Signed in successfully.', ); }, onError: (error: Error) => toast.error(error.message), }); return (
Mobile-first Codex monitor

CodexDash keeps every Codex account in one gorgeous live dashboard.

Sign into CodexDash, connect multiple OpenAI Codex accounts through a real login flow, and view combined limits, remaining usage, raw API payloads, and per-account drilldowns from a single responsive UI.

{[ { icon: Gauge, title: 'Unified usage', desc: 'Merge multiple OpenAI accounts into one overview.', }, { icon: ShieldCheck, title: 'Stored safely', desc: 'OAuth session data is encrypted at rest.', }, { icon: Activity, title: 'Live detail', desc: 'See refreshed usage plus raw usage payloads.', }, ].map((item) => (
{item.title}
{item.desc}
))}
{mode === 'register' ? 'Create your account' : 'Welcome back'} {mode === 'register' ? 'Start with your CodexDash account, then connect OpenAI Codex logins inside the dashboard.' : 'Log in to continue monitoring your combined Codex usage.'}
mutation.mutate(values))} > {mode === 'register' ? (

{String(form.formState.errors.name?.message ?? '')}

) : null}

{String(form.formState.errors.email?.message ?? '')}

{String(form.formState.errors.password?.message ?? '')}

OpenAI account connection now uses a real sign-in flow based on the Codex client OAuth pattern. After you click connect, CodexDash opens OpenAI login in a popup and can also finish from a pasted callback URL if localhost is unavailable.

); } function ConnectAccountDialog() { const queryClient = useQueryClient(); const [open, setOpen] = useState(false); const [attemptId, setAttemptId] = useState(null); const [authorizeUrl, setAuthorizeUrl] = useState(null); const popupRef = useRef(null); const handledAttemptStatusRef = useRef(null); const form = useForm>({ resolver: zodResolver(connectSchema), defaultValues: { label: '', emailHint: '' }, }); const manualCallbackForm = useForm>({ resolver: zodResolver(manualCallbackSchema), defaultValues: { callbackUrl: '' }, }); const startMutation = useMutation({ mutationFn: api.startCodexLogin, onSuccess: (response) => { setAttemptId(response.attemptId); setAuthorizeUrl(response.authorizeUrl); manualCallbackForm.reset(); popupRef.current = window.open( response.authorizeUrl, 'codexdash-openai-login', 'popup=yes,width=520,height=760', ); if (!popupRef.current) { toast.error('Popup was blocked. Use the fallback link inside the dialog.'); } else { toast.success('Continue the OpenAI sign-in flow in the popup.'); } }, onError: (error: Error) => toast.error(error.message), }); const manualCompleteMutation = useMutation({ mutationFn: ({ callbackUrl, currentAttemptId, }: CompleteCodexManualLoginInput & { currentAttemptId: string }) => api.completeCodexManualLogin(currentAttemptId, { callbackUrl }), onSuccess: () => { toast.success('Processing the pasted OpenAI callback URL…'); void attemptQuery.refetch(); }, onError: (error: Error) => toast.error(error.message), }); const attemptQuery = useQuery({ enabled: Boolean(attemptId), queryKey: ['codex-login-attempt', attemptId], queryFn: () => api.getCodexLoginAttempt(attemptId as string), refetchInterval: (query) => query.state.data?.status === 'pending' ? 2_000 : false, }); const cancelMutation = useMutation({ mutationFn: api.cancelCodexLoginAttempt, onSuccess: () => { toast.success('Login attempt cancelled.'); setAttemptId(null); setAuthorizeUrl(null); manualCallbackForm.reset(); popupRef.current?.close(); }, onError: (error: Error) => toast.error(error.message), }); useEffect(() => { const attempt = attemptQuery.data; if (!attempt) { return; } const statusKey = `${attempt.id}:${attempt.status}:${attempt.completedAt ?? ''}:${attempt.lastError ?? ''}`; if (handledAttemptStatusRef.current === statusKey) { return; } if (attempt.status === 'completed') { handledAttemptStatusRef.current = statusKey; window.setTimeout(() => { toast.success('OpenAI Codex account connected.'); setOpen(false); setAttemptId(null); setAuthorizeUrl(null); form.reset(); manualCallbackForm.reset(); popupRef.current?.close(); void queryClient.invalidateQueries({ queryKey: ['usage-summary'] }); }, 0); return; } if (attempt.status === 'error' || attempt.status === 'expired') { handledAttemptStatusRef.current = statusKey; toast.error(attempt.lastError || 'OpenAI login failed.'); } }, [attemptQuery.data, form, manualCallbackForm, queryClient]); useEffect(() => { function onMessage(event: MessageEvent) { if (event.data?.type !== 'codexdash:oauth-complete') { return; } if (event.data?.attemptId && event.data.attemptId === attemptId) { void attemptQuery.refetch(); } } window.addEventListener('message', onMessage); return () => window.removeEventListener('message', onMessage); }, [attemptId, attemptQuery]); const attempt = attemptQuery.data; const isPendingAttempt = attempt?.status === 'pending'; return ( { setOpen(next); if (!next && isPendingAttempt && attemptId) { cancelMutation.mutate(attemptId); } }} > Connect an OpenAI Codex account Start a real OpenAI sign-in flow. CodexDash opens the official login, completes the Codex-style OAuth callback locally, then stores the encrypted session for future usage refreshes. {attemptId ? (
Waiting for OpenAI login
{attempt?.status === 'completed' ? 'The login finished successfully. Closing this dialog…' : 'Finish the sign-in flow in the popup window. CodexDash will detect the callback automatically.'}
Expires: {formatDate(attempt?.expiresAt ?? null)}
{authorizeUrl ? (
) : null}
Manual fallback

If localhost:1455 is not listening, OpenAI may finish on a browser error page. Copy the full URL from the address bar and paste it below to complete the login manually.

{ if (!attemptId) { return; } manualCompleteMutation.mutate({ callbackUrl: values.callbackUrl, currentAttemptId: attemptId, }); })} >

{String( manualCallbackForm.formState.errors.callbackUrl?.message ?? '', )}

{attempt?.lastError ? (
{attempt.lastError}
) : null}
) : (
startMutation.mutate(values as StartCodexLoginInput) )} >

{String(form.formState.errors.label?.message ?? '')}

CodexDash opens the official OpenAI sign-in flow in a popup and also supports a manual pasted-URL fallback when the local callback bridge is unavailable.
)}
); } function Dashboard() { const queryClient = useQueryClient(); const summaryQuery = useQuery({ queryKey: ['usage-summary'], queryFn: () => api.getUsageSummary(true), }); const userQuery = useQuery({ queryKey: ['me'], queryFn: api.me }); const deleteMutation = useMutation({ mutationFn: api.deleteAccount, onSuccess: () => { toast.success('OpenAI account removed.'); void queryClient.invalidateQueries({ queryKey: ['usage-summary'] }); }, onError: (error: Error) => toast.error(error.message), }); if (summaryQuery.isLoading || userQuery.isLoading) { return (
Loading CodexDash…
); } if (summaryQuery.isError || userQuery.isError) { return (
Unable to load dashboard {(summaryQuery.error as Error | undefined)?.message ?? (userQuery.error as Error | undefined)?.message}
); } const summary = summaryQuery.data!; const user = userQuery.data!; const usageWindows = summarizeUsageWindows( summary.accounts.map((account) => account.usage), ); const windowCards = [ { title: 'Primary window', tone: 'text-sky-300', window: usageWindows.primary, }, { title: 'Secondary window', tone: 'text-violet-300', window: usageWindows.secondary, }, ].filter( (item): item is { title: string; tone: string; window: NonNullable; } => item.window !== null, ); const fastestResetAt = getFastestResetAt( windowCards.map((item) => item.window.resetAt), ); const accountCapacityItems = summary.accounts.map((account) => { const accountWindows = extractUsageWindows(account.usage); const accountCapacityBars = [accountWindows.primary, accountWindows.secondary].filter( (window): window is NonNullable => window !== null, ); return { account, accountCapacityBars, }; }); return (
Signed in as {user.name}

CodexDash overview

Combined usage is refreshed by calling Codex usage endpoints for each attached OpenAI account and merging numeric fields into one dashboard.

Unified capacity {windowCards.length > 0 ? (
{windowCards.map((item) => { const usedPercent = item.window.usedPercent; const progressValue = usedPercent !== null && usedPercent !== undefined ? Math.max(0, Math.min(100, usedPercent)) : 0; return (
{item.title}
{usedPercent !== null && usedPercent !== undefined ? `${usedPercent.toFixed(0)}%` : '—'}
{item.window.limitWindowSeconds !== null ? (
{formatDurationSeconds(item.window.limitWindowSeconds)}
) : null}
Replenishes at {formatDate(item.window.resetAt)}
); })}
) : (
No rate-limit window data yet. Connect an OpenAI account and refresh to load Codex usage windows.
)}
{fastestResetAt ? ( Earliest replenishment {formatDate(fastestResetAt)} ) : null} Accounts: {summary.totals.totalAccounts} Healthy: {summary.totals.activeAccounts} Errors: {summary.totals.erroredAccounts} Updated: {formatDate(summary.refreshedAt)}
{[ { title: 'Connected sessions', value: summary.totals.totalAccounts, tone: 'text-sky-300', }, { title: 'Healthy sessions', value: summary.totals.activeAccounts, tone: 'text-emerald-300', }, { title: 'Errored sessions', value: summary.totals.erroredAccounts, tone: 'text-rose-300', }, ].map((item) => ( {item.title} {item.value.toLocaleString()} ))}
Connected OpenAI accounts Merged by default. Inspect each account below. {summary.accounts.length === 0 ? (
No OpenAI accounts connected yet.
) : ( {summary.accounts.map((account) => ( {account.label} ))} {summary.accounts.map((account) => (
{account.label}
{account.providerEmail || account.emailHint || 'No email available yet'}
{account.status}
Auth: {account.authType}
Plan: {account.planType || 'Unknown'}
Provider account:{' '} {account.providerAccountId || 'Unknown'}
Session expires: {formatDate(account.sessionExpiresAt)}
Last synced: {formatDate(account.lastSyncedAt)}
Connected: {formatDate(account.createdAt)}
Error:{' '} {account.lastError || 'None'}
))}
)}
Per-account capacity Compact rate-limit bars for each connected OpenAI account. {accountCapacityItems.length === 0 ? (
No account capacity data yet.
) : (
{accountCapacityItems.map(({ account, accountCapacityBars }) => (
{account.label}
{account.providerEmail || account.emailHint || 'No email available yet'}
{account.status}
{accountCapacityBars.length > 0 ? (
{accountCapacityBars.map((window, index) => { const progressValue = window.usedPercent !== null ? Math.max(0, Math.min(100, window.usedPercent)) : 0; return (
{window.usedPercent !== null ? `${window.usedPercent.toFixed(0)}%` : '—'}
); })}
) : (
No window data yet.
)}
))}
)}
); } export default function App() { const [authenticated, setAuthenticated] = useState(Boolean(getToken())); return (
{authenticated ? ( ) : ( setAuthenticated(true)} /> )}
); }