Files
claudia/src/components/ClaudeBinaryDialog.tsx
2025-06-19 19:24:01 +05:30

104 lines
3.6 KiB
TypeScript

import { useState } from "react";
import { api } from "@/lib/api";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { ExternalLink, FileQuestion, Terminal } from "lucide-react";
interface ClaudeBinaryDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onSuccess: () => void;
onError: (message: string) => void;
}
export function ClaudeBinaryDialog({ open, onOpenChange, onSuccess, onError }: ClaudeBinaryDialogProps) {
const [binaryPath, setBinaryPath] = useState("");
const [isValidating, setIsValidating] = useState(false);
const handleSave = async () => {
if (!binaryPath.trim()) {
onError("Please enter a valid path");
return;
}
setIsValidating(true);
try {
await api.setClaudeBinaryPath(binaryPath.trim());
onSuccess();
onOpenChange(false);
} catch (error) {
console.error("Failed to save Claude binary path:", error);
onError(error instanceof Error ? error.message : "Failed to save Claude binary path");
} finally {
setIsValidating(false);
}
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<FileQuestion className="w-5 h-5" />
Couldn't locate Claude Code installation
</DialogTitle>
<DialogDescription className="space-y-3 mt-4">
<p>
Claude Code was not found in any of the common installation locations.
Please specify the path to the Claude binary manually.
</p>
<div className="flex items-center gap-2 p-3 bg-muted rounded-md">
<Terminal className="w-4 h-4 text-muted-foreground" />
<p className="text-sm text-muted-foreground">
<span className="font-medium">Tip:</span> Run{" "}
<code className="px-1 py-0.5 bg-black/10 dark:bg-white/10 rounded">which claude</code>{" "}
in your terminal to find the installation path
</p>
</div>
</DialogDescription>
</DialogHeader>
<div className="py-4">
<Input
type="text"
placeholder="/usr/local/bin/claude"
value={binaryPath}
onChange={(e) => setBinaryPath(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter" && !isValidating) {
handleSave();
}
}}
autoFocus
className="font-mono text-sm"
/>
<p className="text-xs text-muted-foreground mt-2">
Common locations: /usr/local/bin/claude, /opt/homebrew/bin/claude, ~/.claude/local/claude
</p>
</div>
<DialogFooter className="gap-3">
<Button
variant="outline"
onClick={() => window.open("https://docs.claude.ai/claude/how-to-install", "_blank")}
className="mr-auto"
>
<ExternalLink className="w-4 h-4 mr-2" />
Installation Guide
</Button>
<Button
variant="outline"
onClick={() => onOpenChange(false)}
disabled={isValidating}
>
Cancel
</Button>
<Button onClick={handleSave} disabled={isValidating || !binaryPath.trim()}>
{isValidating ? "Validating..." : "Save Path"}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}