fix: align first-run modal with local OpenAI key settings

- check configured key status through the settings API
- dismiss first-run modal with a dedicated local storage flag
- treat .env.local as the local OpenAI key source

Generated with Claude Code
This commit is contained in:
“BeeRad”
2026-04-20 17:11:19 +10:00
parent c0c896cf8b
commit 14b5784cd6
2 changed files with 28 additions and 10 deletions
+25 -4
View File
@@ -2,20 +2,41 @@
import { useState, useEffect, type CSSProperties } from 'react'; import { useState, useEffect, type CSSProperties } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { isFirstRun, markFirstRunComplete } from '@/services/storage/apiKeys';
import { openExternalUrl } from '@/utils/openExternalUrl'; import { openExternalUrl } from '@/utils/openExternalUrl';
const FIRST_RUN_DISMISSED_KEY = 'ra-h-os.first-run.dismissed.v1';
export default function FirstRunModal() { export default function FirstRunModal() {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
useEffect(() => { useEffect(() => {
if (isFirstRun()) { let cancelled = false;
setIsOpen(true);
void (async () => {
try {
const response = await fetch('/api/settings/openai-key');
if (!response.ok) return;
const data = await response.json();
if (cancelled) return;
const dismissed = window.localStorage.getItem(FIRST_RUN_DISMISSED_KEY) === 'true';
setIsOpen(!data.configured && !dismissed);
} catch {
if (!cancelled) {
const dismissed = window.localStorage.getItem(FIRST_RUN_DISMISSED_KEY) === 'true';
setIsOpen(!dismissed);
} }
}
})();
return () => {
cancelled = true;
};
}, []); }, []);
const handleClose = () => { const handleClose = () => {
markFirstRunComplete(); window.localStorage.setItem(FIRST_RUN_DISMISSED_KEY, 'true');
setIsOpen(false); setIsOpen(false);
}; };
+2 -5
View File
@@ -26,12 +26,9 @@ export function getPreferredOpenAiKey(): string | undefined {
const fileKey = parseOpenAiKeyFromEnvFile(fs.readFileSync(envPath, 'utf8')); const fileKey = parseOpenAiKeyFromEnvFile(fs.readFileSync(envPath, 'utf8'));
if (fileKey) return fileKey; if (fileKey) return fileKey;
} catch { } catch {
// Ignore missing/unreadable .env.local and fall back to process env. // Ignore missing/unreadable .env.local and treat that as "not configured" for local mode.
} }
return undefined;
const envKey = process.env.OPENAI_API_KEY;
if (!envKey || envKey === PLACEHOLDER) return undefined;
return envKey;
} }
export function hasPreferredOpenAiKey(): boolean { export function hasPreferredOpenAiKey(): boolean {