Spaces:
Running
Running
"use client" | |
import { Suspense, useEffect, useState, useTransition } from "react" | |
import { Post } from "@/types" | |
import { cn } from "@/lib/utils" | |
import { actionman } from "@/lib/fonts" | |
import { getLatestPosts } from "../engine/community" | |
import { useSearchParams } from "next/navigation" | |
import { Button } from "@/components/ui/button" | |
import { Delete } from "./delete" | |
import Link from "next/link" | |
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" | |
function PageContent() { | |
const searchParams = useSearchParams() | |
const [_isPending, startTransition] = useTransition() | |
const [posts, setPosts] = useState<Post[]>([]) | |
const moderationKey = (searchParams.get("moderationKey") as string) || "" | |
const [toDelete, setToDelete] = useState<Post>() | |
useEffect(() => { | |
startTransition(async () => { | |
const newPosts = await getLatestPosts({ | |
maxNbPosts: 50, | |
}) | |
setPosts(newPosts) | |
}) | |
}, []) | |
const handleOnDelete = ({ postId }: Post) => { | |
setPosts(posts.filter(post => post.postId !== postId)) | |
setToDelete(undefined) | |
} | |
return ( | |
<> | |
<div className="w-full flex flex-col items-center overflow-y-scroll"> | |
<div className="flex flex-col space-y-2 pt-18 mb-6"> | |
<h1 className="text-4xl md:text-6xl lg:text-[70px] xl:text-[100px] text-cyan-700">π Text-to-panorama</h1> | |
<h2 className="text-3xl mb-6">Generate cool panoramas using AI!</h2> | |
<h2 className="text-2xl">Latest locations synthesized:</h2> | |
</div> | |
<div className="w-full grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-x-4 gap-y-6 px-12"> | |
{posts.map(post => ( | |
<Link | |
key={post.postId} | |
href={`/?postId=${post.postId}`} | |
target="_blank"> | |
<div | |
key={post.postId} | |
className="group flex flex-col cursor-pointer" | |
> | |
<div className="w-full h-32"> | |
{moderationKey ? <div className="relative -mb-8 ml-2"> | |
<Button | |
className="z-30 bg-red-200 text-red-700 hover:bg-red-300 hover:text-red-800 text-2xs px-2 h-7" | |
onClick={(e) => { | |
e.preventDefault() | |
setToDelete(post) | |
return false | |
}}>Delete</Button> | |
</div> : null} | |
<img | |
src={post.assetUrl} | |
className={cn( | |
`w-full h-32 rounded-xl overflow-hidden object-cover`, | |
`border border-zinc-900/70`, | |
// `group-hover:brightness-105` | |
)} | |
/> | |
</div> | |
<Tooltip> | |
<TooltipTrigger asChild> | |
<div | |
className="text-base text-stone-900/80 truncate w-full group-hover:underline underline-offset-2" | |
>{post.prompt}</div> | |
</TooltipTrigger> | |
<TooltipContent> | |
<p className="w-full max-w-xl">{post.prompt}</p> | |
</TooltipContent> | |
</Tooltip> | |
<div | |
className="text-sm text-stone-700/70 w-full group-hover:underline underline-offset-2" | |
>{new Date(Date.parse(post.createdAt)).toLocaleString()}</div> | |
</div> | |
</Link> | |
))} | |
</div> | |
</div> | |
<Delete post={toDelete} moderationKey={moderationKey} onDelete={handleOnDelete} /> | |
</> | |
) | |
} | |
export default function FirehosePage() { | |
return ( | |
<TooltipProvider delayDuration={100}> | |
<div className={cn( | |
`light fixed w-full h-full flex flex-col items-center bg-slate-300 text-slate-800`, | |
``, | |
actionman.className | |
)}> | |
<Suspense><PageContent /></Suspense> | |
</div> | |
</TooltipProvider> | |
) | |
} |