import { ScrollView, View, Text, TouchableOpacity, ActivityIndicator, RefreshControl, } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import { MaterialIcons } from "@expo/vector-icons"; import { useCodexUsage } from "@/hooks/useCodexUsage"; import { UsageStat } from "@/components/UsageStat"; import { ErrorMessage } from "@/components/ErrorMessage"; import { LastUpdated } from "@/components/LastUpdated"; import { ScreenErrorBoundary } from "@/components/ScreenErrorBoundary"; import { COLORS } from "@/lib/constants"; import { windowLabel } from "@/lib/timeUtils"; import type { CodexResetCredit } from "@/types/codex"; function formatResetStatus(status?: string) { if (!status) return "Unknown"; return status.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()); } function ResetCreditRow({ credit }: { credit: CodexResetCredit }) { return ( Credit {credit.index} {formatResetStatus(credit.status)} {credit.timeUntilExpiry && ( Expires in {credit.timeUntilExpiry} )} {credit.expiresAtLocal && ( Expires {credit.expiresAtLocal} )} {credit.grantedAtLocal && ( Granted {credit.grantedAtLocal} )} ); } function CodexTabContent() { const { auth, usage, lastFetchedAt, status, error, importAuthFile, refresh, clearAuth, } = useCodexUsage(); const resetCoupons = usage?.resetCoupons; const availableResetCredits = resetCoupons?.credits?.filter((credit) => credit.status === "available") ?? []; return ( } > {/* Header */} Codex CLI Rate limits & credits {/* Configuration card */} Configuration {auth ? ( Connected {auth.accountId && ( {auth.accountId.slice(0, 10)}… )} Clear ) : ( Import auth.json Located at ~/.codex/auth.json )} {/* Usage card */} Usage {status === "idle" && !auth && ( Import auth.json to see your rate limits )} {status === "loading" && !usage && ( )} {status === "error" && error && } {usage && ( {/* Plan badge */} {usage.planType ?? "codex"} {usage.primary && ( )} {usage.secondary && ( )} {/* Credits */} Credits {usage.credits.unlimited ? ( Unlimited ) : usage.credits.hasCredits ? ( ${Number(usage.credits.balance).toFixed(2)} remaining ) : ( No credits )} {resetCoupons && ( Reset Credits {resetCoupons.availableCount ?? 0} available {typeof resetCoupons.totalEarnedCount === "number" && ( {resetCoupons.totalEarnedCount} earned total )} {resetCoupons.nextExpiringCredit?.expiresAtLocal && ( Next expires {resetCoupons.nextExpiringCredit.expiresAtLocal} )} {resetCoupons.nextExpiringCredit?.timeUntilExpiry && ( In {resetCoupons.nextExpiringCredit.timeUntilExpiry} )} {availableResetCredits.length > 0 && ( Available Now {availableResetCredits.map((credit) => ( ))} )} {resetCoupons.source !== "live_api" && ( Source: {resetCoupons.sourceDescription} )} )} )} ); } export default function CodexTab() { return ( ); }