132 lines
3.4 KiB
TypeScript
132 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import Image from "next/image";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
|
import { Copy, Play, Twitter } from "lucide-react";
|
|
|
|
import PostgrestError from "@/lib/config";
|
|
|
|
import { createClient } from "@/utils/supabase/client";
|
|
import { Tables } from "@/utils/supabase/database.types";
|
|
|
|
import { toast } from "sonner";
|
|
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { Button, buttonVariants } from "@/components/ui/button";
|
|
|
|
import Spinner from "@/components/spinner";
|
|
|
|
type ResponseAgentCardProps = {
|
|
agentResponseId: string;
|
|
};
|
|
|
|
export default function ResponseAgentCard({
|
|
agentResponseId,
|
|
}: ResponseAgentCardProps) {
|
|
const {
|
|
data: responseData,
|
|
isLoading,
|
|
error,
|
|
} = useQuery({
|
|
retry: 0,
|
|
queryKey: ["agent-responses", agentResponseId],
|
|
queryFn: async ({ signal }) => {
|
|
const supabase = createClient();
|
|
|
|
const response = await supabase
|
|
.from("agent_responses")
|
|
.select(
|
|
`
|
|
*,
|
|
agents (
|
|
agent_id:id,
|
|
name,
|
|
image_url
|
|
)
|
|
`
|
|
)
|
|
.eq("id", agentResponseId)
|
|
.limit(1)
|
|
.single();
|
|
|
|
if (response.error) throw new PostgrestError(response.error);
|
|
|
|
return response;
|
|
},
|
|
});
|
|
|
|
if (error) return <p className="text-center">{error.message}</p>;
|
|
|
|
if (isLoading || !responseData || !responseData.data)
|
|
return <Spinner className="mx-auto" />;
|
|
|
|
return <CardContent agentResponse={responseData.data} />;
|
|
}
|
|
|
|
const CardContent = ({
|
|
agentResponse,
|
|
}: {
|
|
agentResponse: Tables<"agent_responses"> & {
|
|
agents: {
|
|
agent_id: number;
|
|
name: string;
|
|
image_url: string;
|
|
};
|
|
};
|
|
}) => {
|
|
const { id, agent_id, question, response, agents } = agentResponse;
|
|
|
|
return (
|
|
<>
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<figure className="relative h-16 w-16 rounded-full overflow-hidden">
|
|
<Image
|
|
src={agents.image_url}
|
|
fill={true}
|
|
alt="test"
|
|
className="object-cover"
|
|
/>
|
|
</figure>
|
|
<div>
|
|
<h1 className="text-primary">{agents.name}</h1>
|
|
<p className="text-gray-400 text-sm">{id}</p>
|
|
</div>
|
|
</div>
|
|
<Separator className="mb-3" />
|
|
<h2 className="text-sm font-bold text-primary mb-2">Question: </h2>
|
|
<p className="text-gray-500 text-sm mb-3">{question}</p>
|
|
<h2 className="text-sm font-bold text-primary mb-2">Response: </h2>
|
|
<p className="text-gray-500 text-sm mb-3">{response}</p>
|
|
<Separator className="mb-4" />
|
|
<div className="grid grid-cols-3 gap-3">
|
|
<Link
|
|
href={encodeURI(`https://x.com/intent/post?text=${response}`)}
|
|
target="blank"
|
|
className={buttonVariants({ variant: "outline" })}
|
|
>
|
|
<Twitter className="h-4 w-4 mr-2" /> Share on Twitter
|
|
</Link>
|
|
<Link
|
|
href={`/agents/${agent_id}`}
|
|
className={buttonVariants({ variant: "default" })}
|
|
>
|
|
<Play className="h-4 w-4 mr-2" /> Ask Another
|
|
</Link>
|
|
<Button
|
|
variant={"outline"}
|
|
onClick={() => {
|
|
navigator.clipboard.writeText(window.location.href);
|
|
toast.info("Copied to clipboard!");
|
|
}}
|
|
>
|
|
<Copy className="h-4 w-4 mr-2" />
|
|
Copy Link
|
|
</Button>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|