82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import { Card, CardContent } from "@/components/ui/card";
|
|
import { Separator } from "@/components/ui/separator";
|
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
import { getConversations } from "@/services/get-conversations";
|
|
import type { ConversationModel } from "@/types/conversation-model";
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { Link } from "@tanstack/react-router";
|
|
import { ArrowRightIcon } from "lucide-react";
|
|
|
|
const ConversationsSkeleton = () => {
|
|
return Array(4)
|
|
.fill(null)
|
|
.map((_, index) => (
|
|
<div key={index} className="flex w-full gap-3">
|
|
<Skeleton className="w-12 h-12 rounded-md" />
|
|
<div className="flex flex-col justify-between flex-1">
|
|
<Skeleton className="w-full h-4" />
|
|
<Skeleton className="w-full h-4" />
|
|
</div>
|
|
</div>
|
|
));
|
|
};
|
|
|
|
interface ConversationsListProps {
|
|
items: ConversationModel[];
|
|
}
|
|
const ConversationsList = ({ items }: Readonly<ConversationsListProps>) => {
|
|
if (!items || !items.length) {
|
|
return <div>No conversations found. Create one!</div>;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
{items.map((c, idx) => (
|
|
<>
|
|
<Link
|
|
to="/conversation/$sessionId"
|
|
params={{ sessionId: c.session_id }}
|
|
className="flex items-center gap-3 rounded-sm hover:bg-neutral-50 transition-colors px-2 py-4"
|
|
>
|
|
<ArrowRightIcon />
|
|
<div className="flex flex-col gap-1">
|
|
<span className="font-semibold">{c.title}</span>
|
|
<span className="text-neutral-500 text-xs">
|
|
Created: {new Date(c.created).toLocaleDateString()}{" "}
|
|
{new Date(c.created).toLocaleTimeString()}
|
|
</span>
|
|
</div>
|
|
</Link>
|
|
{idx < items.length - 1 && <Separator orientation="horizontal" />}
|
|
</>
|
|
))}
|
|
</>
|
|
);
|
|
};
|
|
|
|
const ConversationsHistory = () => {
|
|
const { isPending, data } = useQuery({
|
|
queryKey: [getConversations.queryKey],
|
|
queryFn: getConversations,
|
|
});
|
|
|
|
return (
|
|
<div className="flex flex-col gap-3">
|
|
<span className="text-lg font-bold">Conversations history</span>
|
|
<Card className="w-fit min-w-[650px]">
|
|
<CardContent>
|
|
<div className="flex flex-col gap-3">
|
|
{isPending ? (
|
|
<ConversationsSkeleton />
|
|
) : (
|
|
<ConversationsList items={data?.conversations || []} />
|
|
)}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ConversationsHistory;
|