mirror of
https://github.com/hex248/ob248.com.git
synced 2026-02-07 18:23:04 +00:00
ask ai
This commit is contained in:
88
src/components/ask-ai.tsx
Normal file
88
src/components/ask-ai.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
import { AI_SUMMARY_PROMPT } from "@/lib/constants";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Icon } from "@iconify/react";
|
||||
import { Copy } from "@nsmr/pixelart-react";
|
||||
import { useRef, useState } from "react";
|
||||
|
||||
const chatGptUrl = "https://chat.openai.com/?q=";
|
||||
const claudeUrl = "https://claude.ai/new?q=";
|
||||
|
||||
export function AskAI({
|
||||
name,
|
||||
prompt = AI_SUMMARY_PROMPT,
|
||||
inline = false,
|
||||
}: {
|
||||
name: string;
|
||||
prompt?: string;
|
||||
inline?: boolean;
|
||||
}) {
|
||||
const encodedPrompt = encodeURIComponent(prompt);
|
||||
const [copied, setCopied] = useState(false);
|
||||
const timeoutRef = useRef<number | null>(null);
|
||||
|
||||
const handleCopy = async () => {
|
||||
if (!navigator.clipboard) return;
|
||||
try {
|
||||
await navigator.clipboard.writeText(prompt);
|
||||
setCopied(true);
|
||||
if (timeoutRef.current) {
|
||||
window.clearTimeout(timeoutRef.current);
|
||||
}
|
||||
timeoutRef.current = window.setTimeout(() => {
|
||||
setCopied(false);
|
||||
}, 1500);
|
||||
} catch {
|
||||
setCopied(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col items-end gap-2",
|
||||
inline && "flex-row items-center gap-4",
|
||||
)}
|
||||
>
|
||||
<p className="text-fg text-lg text-pretty">Ask AI about {name}:</p>
|
||||
<div className="flex items-center gap-4">
|
||||
<a
|
||||
href={chatGptUrl + encodedPrompt}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-fg hover:text-accent"
|
||||
title={"Ask ChatGPT"}
|
||||
>
|
||||
<Icon icon="simple-icons:openai" className="size-6" />
|
||||
</a>
|
||||
<a
|
||||
href={`${claudeUrl}${encodedPrompt}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-fg hover:text-accent"
|
||||
title="Ask Claude"
|
||||
>
|
||||
<Icon icon="simple-icons:claude" className="size-6" />
|
||||
</a>
|
||||
<div className="relative flex items-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleCopy}
|
||||
className="text-fg hover:text-accent cursor-pointer flex items-center"
|
||||
title="Copy prompt to clipboard"
|
||||
aria-label="Copy prompt to clipboard"
|
||||
>
|
||||
<Copy className="size-6" />
|
||||
</button>
|
||||
<span
|
||||
className={cn(
|
||||
"absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-2 py-1 text-xs bg-background border opacity-0 pointer-events-none whitespace-nowrap",
|
||||
copied && "opacity-100",
|
||||
)}
|
||||
>
|
||||
Copied to clipboard
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
10
src/lib/constants.ts
Normal file
10
src/lib/constants.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export const AI_SUMMARY_PROMPT =
|
||||
"I am a recruiter, tell me about Oliver Bryan, a software developer. What would he bring to the table? Review his portfolio at ob248.com and summarize his key strengths, technical skills, and notable projects. What makes him stand out as a candidate?";
|
||||
|
||||
export function getProjectPrompt(
|
||||
projectName: string,
|
||||
projectDescription: string,
|
||||
projectSlug: string,
|
||||
): string {
|
||||
return `Tell me about "${projectName}", a project by Oliver Bryan. ${projectDescription} Review the project page at ob248.com/projects/${projectSlug} and explain the technical decisions, technologies used, and what this project demonstrates about Oliver's skills as a developer. Provide any url or repository that would be helpful.`;
|
||||
}
|
||||
Reference in New Issue
Block a user