page.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. "use client";
  2. import { AgentGrid } from "@/components/agent-grid";
  3. import { Header } from "@/components/header";
  4. import { motion, useScroll, useTransform } from "framer-motion";
  5. import dynamic from "next/dynamic";
  6. import { ConnectButton } from "@rainbow-me/rainbowkit";
  7. import { Agent } from "@/types/agent";
  8. import { useEffect, useState } from "react";
  9. import { fetchAgentStats } from "@/lib/agents";
  10. // 👇 Dynamically import the provider to avoid server-side import trace
  11. const ClientQueryProvider = dynamic(() => import("./ClientQueryProvider").then(mod => mod.QueryProvider), {
  12. ssr: false,
  13. });
  14. function HomeContent() {
  15. const { scrollY } = useScroll();
  16. const backgroundColor = useTransform(scrollY, [0, 300], ["rgb(26, 26, 46)", "rgb(255, 255, 255)"]);
  17. const [agents, setAgents] = useState<Agent[] | null>(null);
  18. const [loading, setLoading] = useState<boolean>(true);
  19. const [error, setError] = useState<string | null>(null);
  20. const updateAgent = (updatedAgent: Agent) => {
  21. setAgents(prevAgents =>
  22. prevAgents
  23. ? prevAgents.map(agent =>
  24. agent.agentId === updatedAgent.agentId ? updatedAgent : agent
  25. )
  26. : null
  27. );
  28. };
  29. useEffect(() => {
  30. let isMounted = true;
  31. const loadAgents = async () => {
  32. setLoading(true);
  33. setError(null);
  34. try {
  35. const res = await fetch("/api/agents");
  36. if (!res.ok) throw new Error("Failed to fetch agents. ");
  37. const data = await res.json();
  38. const agents = await fetchAgentStats(data);
  39. if (isMounted) {
  40. setAgents(Array.isArray(agents) ? agents : [agents]);
  41. }
  42. } catch (err: any) {
  43. if (isMounted) {
  44. setError(err.message || "Error loading agents.");
  45. }
  46. } finally {
  47. if (isMounted) {
  48. setLoading(false);
  49. }
  50. }
  51. };
  52. loadAgents();
  53. return () => {
  54. isMounted = false;
  55. };
  56. }, []);
  57. return (
  58. <motion.main className="min-h-screen" style={{ backgroundColor }}>
  59. <div className="absolute top-4 right-4 z-30">
  60. <ConnectButton />
  61. </div>
  62. <Header />
  63. <div className="sticky top-0 z-20 bg-white/80 backdrop-blur-sm border-b">
  64. {error ? (
  65. <div className="p-4 text-red-500">Error loading agents: {error}</div>
  66. ) : loading ? (
  67. <div className="flex justify-center items-center p-8">
  68. <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-gray-900"></div>
  69. </div>
  70. ) : (
  71. <AgentGrid agents={agents!} onUpdateAgent={updateAgent}/>
  72. )}
  73. </div>
  74. </motion.main>
  75. );
  76. }
  77. export default function Page() {
  78. return (
  79. <ClientQueryProvider>
  80. <HomeContent />
  81. </ClientQueryProvider>
  82. );
  83. }