"use client"; import { motion, type Variants } from "framer-motion"; import { AlertCircle, Loader2, Plus, Search, Trash2 } from "lucide-react"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { toast } from "sonner"; import { Logo } from "@/components/Logo"; import { ThemeTogglerComponent } from "@/components/theme/theme-toggle"; import { UserDropdown } from "@/components/UserDropdown"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { Spotlight } from "@/components/ui/spotlight"; import { Tilt } from "@/components/ui/tilt"; import { useSearchSpaces } from "@/hooks/use-search-spaces"; import { apiClient } from "@/lib/api"; interface User { id: string; email: string; is_active: boolean; is_superuser: boolean; is_verified: boolean; } /** * Formats a date string into a readable format * @param dateString - The date string to format * @returns Formatted date string (e.g., "Jan 1, 2023") */ const formatDate = (dateString: string): string => { return new Date(dateString).toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric", }); }; /** * Loading screen component with animation */ const LoadingScreen = () => { return (
Loading Fetching your search spaces... This may take a moment
); }; /** * Error screen component with animation */ const ErrorScreen = ({ message }: { message: string }) => { const router = useRouter(); return (
Error
Something went wrong
Error Details {message}
); }; const DashboardPage = () => { // Animation variants const containerVariants: Variants = { hidden: { opacity: 0 }, visible: { opacity: 1, transition: { staggerChildren: 0.1, }, }, }; const itemVariants: Variants = { hidden: { y: 20, opacity: 0 }, visible: { y: 0, opacity: 1, transition: { type: "spring", stiffness: 300, damping: 24, }, }, }; const { searchSpaces, loading, error, refreshSearchSpaces } = useSearchSpaces(); // User state management const [user, setUser] = useState(null); const [isLoadingUser, setIsLoadingUser] = useState(true); const [userError, setUserError] = useState(null); // Fetch user details useEffect(() => { const fetchUser = async () => { try { if (typeof window === "undefined") return; try { const userData = await apiClient.get("users/me"); setUser(userData); setUserError(null); } catch (error) { console.error("Error fetching user:", error); setUserError(error instanceof Error ? error.message : "Unknown error occurred"); } finally { setIsLoadingUser(false); } } catch (error) { console.error("Error in fetchUser:", error); setIsLoadingUser(false); } }; fetchUser(); }, []); // Create user object for UserDropdown const customUser = { name: user?.email ? user.email.split("@")[0] : "User", email: user?.email || (isLoadingUser ? "Loading..." : userError ? "Error loading user" : "Unknown User"), avatar: "/icon-128.png", // Default avatar }; if (loading) return ; if (error) return ; const handleDeleteSearchSpace = async (id: number) => { // Send DELETE request to the API try { const response = await fetch( `${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${id}`, { method: "DELETE", headers: { Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`, }, } ); if (!response.ok) { toast.error("Failed to delete search space"); throw new Error("Failed to delete search space"); } // Refresh the search spaces list after successful deletion refreshSearchSpaces(); } catch (error) { console.error("Error deleting search space:", error); toast.error("An error occurred while deleting the search space"); return; } toast.success("Search space deleted successfully"); }; return (

SurfSense Dashboard

Welcome to your SurfSense dashboard.

Your Search Spaces

{searchSpaces && searchSpaces.length > 0 && searchSpaces.map((space) => (
{space.name}
Delete Search Space Are you sure you want to delete "{space.name}"? This action cannot be undone. All documents, chats, and podcasts in this search space will be permanently deleted. Cancel handleDeleteSearchSpace(space.id)} className="bg-destructive hover:bg-destructive/90" > Delete

{space.name}

{space.description}

{/* {space.title} */} Created {formatDate(space.created_at)}
))} {searchSpaces.length === 0 && (

No search spaces found

Create your first search space to get started

)} {searchSpaces.length > 0 && (
Add New Search Space
)}
); }; export default DashboardPage;