Skip to content

Commit 3d58359

Browse files
rorarclaude
andcommitted
fix(ux): JSearch selectable in wizard with API key warning + settings link
Previously JSearch was hidden from the dropdown when API key was missing. Now all modules are selectable — unconfigured ones show: - Amber triangle icon in dropdown item (with tooltip on hover) - Amber warning card below select with "Go to Settings → API Keys" link Also: removed unused hasRapidApiKey state, cleaned up onValueChange guard. i18n: automations.configureApiKey in 4 locales. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 560cf02 commit 3d58359

2 files changed

Lines changed: 37 additions & 31 deletions

File tree

src/components/automations/AutomationWizard.tsx

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ export function AutomationWizard({
103103
const { t } = useTranslations();
104104
const [step, setStep] = useState(0);
105105
const [isSubmitting, setIsSubmitting] = useState(false);
106-
const [hasRapidApiKey, setHasRapidApiKey] = useState<boolean | null>(null);
107106
const [availableModules, setAvailableModules] = useState<ModuleManifestSummary[]>([]);
108107
const [configuredKeyModuleIds, setConfiguredKeyModuleIds] = useState<Set<string>>(new Set());
109108
const [aiScoringEnabled, setAiScoringEnabled] = useState(true);
@@ -128,15 +127,11 @@ export function AutomationWizard({
128127
if (open) {
129128
getUserApiKeys().then((result) => {
130129
if (result.success && result.data) {
131-
const hasKey = result.data.some((k) => k.moduleId === "rapidapi");
132-
setHasRapidApiKey(hasKey);
133130
setConfiguredKeyModuleIds(new Set(result.data.map((k) => k.moduleId)));
134131
} else {
135-
setHasRapidApiKey(false);
136132
setConfiguredKeyModuleIds(new Set());
137133
}
138134
}).catch(() => {
139-
setHasRapidApiKey(false);
140135
setConfiguredKeyModuleIds(new Set());
141136
});
142137

@@ -374,11 +369,7 @@ export function AutomationWizard({
374369
<FormLabel>{t("automations.jobBoard")}</FormLabel>
375370
<Select
376371
onValueChange={(val) => {
377-
// Prevent selecting modules that require unconfigured credentials
378-
const mod = availableModules.find((m) => m.moduleId === val);
379-
if (mod?.credential.required && !configuredKeyModuleIds.has(mod.credential.moduleId)) {
380-
return;
381-
}
372+
// Allow selecting any module — warning shown below if key is missing
382373
field.onChange(val);
383374
}}
384375
value={field.value}
@@ -392,25 +383,26 @@ export function AutomationWizard({
392383
<TooltipProvider>
393384
{availableModules.map((mod) => {
394385
const needsKey = mod.credential.required && !configuredKeyModuleIds.has(mod.credential.moduleId);
395-
if (needsKey) {
396-
return (
397-
<Tooltip key={mod.moduleId}>
398-
<TooltipTrigger asChild>
399-
<div className="relative flex cursor-not-allowed select-none items-center rounded-sm px-2 py-1.5 text-sm text-muted-foreground opacity-50">
400-
<AlertTriangle className="h-4 w-4 mr-2 text-destructive" />
401-
{mod.name}
402-
</div>
403-
</TooltipTrigger>
386+
return (
387+
<Tooltip key={mod.moduleId}>
388+
<TooltipTrigger asChild>
389+
<div>
390+
<SelectItem value={mod.moduleId}>
391+
<span className={needsKey ? "flex items-center gap-2" : ""}>
392+
{mod.name}
393+
{needsKey && (
394+
<AlertTriangle className="h-3.5 w-3.5 text-amber-500 inline-block" />
395+
)}
396+
</span>
397+
</SelectItem>
398+
</div>
399+
</TooltipTrigger>
400+
{needsKey && (
404401
<TooltipContent side="left">
405402
<p>{t("automations.jsearchApiKeyRequired")}</p>
406403
</TooltipContent>
407-
</Tooltip>
408-
);
409-
}
410-
return (
411-
<SelectItem key={mod.moduleId} value={mod.moduleId}>
412-
{mod.name}
413-
</SelectItem>
404+
)}
405+
</Tooltip>
414406
);
415407
})}
416408
</TooltipProvider>
@@ -421,13 +413,23 @@ export function AutomationWizard({
421413
const selectedMod = availableModules.find((m) => m.moduleId === jobBoard);
422414
if (!selectedMod) return null;
423415

424-
// Module requires a key that is NOT configured -> yellow warning
416+
// Module requires a key that is NOT configured -> amber warning with link
425417
if (selectedMod.credential.required && !configuredKeyModuleIds.has(selectedMod.credential.moduleId)) {
426418
return (
427-
<p className="flex items-center gap-1.5 text-sm text-amber-600 dark:text-amber-400">
428-
<AlertTriangle className="h-3.5 w-3.5 shrink-0" />
429-
{t("automations.jsearchApiKeyRequired")}
430-
</p>
419+
<div className="rounded-md border border-amber-200 dark:border-amber-800 bg-amber-50 dark:bg-amber-950/30 p-3 space-y-1">
420+
<p className="flex items-center gap-1.5 text-sm font-medium text-amber-700 dark:text-amber-400">
421+
<AlertTriangle className="h-3.5 w-3.5 shrink-0" />
422+
{t("automations.jsearchApiKeyRequired")}
423+
</p>
424+
<a
425+
href="/dashboard/settings"
426+
className="text-xs text-amber-600 dark:text-amber-500 underline hover:no-underline"
427+
target="_blank"
428+
rel="noopener noreferrer"
429+
>
430+
{t("automations.configureApiKey")}
431+
</a>
432+
</div>
431433
);
432434
}
433435

src/i18n/dictionaries/automations.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export const automations = {
209209

210210
// U2: JSearch API Key Check
211211
"automations.jsearchApiKeyRequired": "API Key required — configure in Settings",
212+
"automations.configureApiKey": "Go to Settings → API Keys",
212213
"automations.noApiKeyNeeded": "No API key needed",
213214

214215
// U3: Threshold Toggle
@@ -439,6 +440,7 @@ export const automations = {
439440

440441
// U2: JSearch API Key Check
441442
"automations.jsearchApiKeyRequired": "API-Schlüssel erforderlich — in Einstellungen konfigurieren",
443+
"automations.configureApiKey": "Zu Einstellungen → API-Schlüssel",
442444
"automations.noApiKeyNeeded": "Kein API-Schlüssel erforderlich",
443445

444446
// U3: Threshold Toggle
@@ -669,6 +671,7 @@ export const automations = {
669671

670672
// U2: JSearch API Key Check
671673
"automations.jsearchApiKeyRequired": "Clé API requise — configurer dans les Paramètres",
674+
"automations.configureApiKey": "Aller dans Paramètres → Clés API",
672675
"automations.noApiKeyNeeded": "Aucune clé API requise",
673676

674677
// U3: Threshold Toggle
@@ -899,6 +902,7 @@ export const automations = {
899902

900903
// U2: JSearch API Key Check
901904
"automations.jsearchApiKeyRequired": "Clave API requerida — configurar en Ajustes",
905+
"automations.configureApiKey": "Ir a Ajustes → Claves API",
902906
"automations.noApiKeyNeeded": "No se requiere clave API",
903907

904908
// U3: Threshold Toggle

0 commit comments

Comments
 (0)