Spaces:
Configuration error
Configuration error
| import { Suspense } from "react" | |
| import { Metadata } from "next" | |
| import prisma from "@/lib/prisma" | |
| import { ExploreClient } from "@/components/explore/explore-client" | |
| import { Loader2 } from "lucide-react" | |
| import { generateSEO } from "@/lib/seo" | |
| const BASE_URL = process.env.NEXT_PUBLIC_APP_URL || 'https://open-prompt.netlify.app' | |
| // Revalidate every 30 seconds instead of force-dynamic | |
| export const revalidate = 30 | |
| export const metadata: Metadata = generateSEO({ | |
| title: "Explore AI Prompts | OpenPrompt", | |
| description: "Discover and run AI prompts created by the community. Find prompts for content, coding, marketing, business, education, and more.", | |
| url: `${BASE_URL}/explore`, | |
| keywords: ["explore prompts", "discover AI prompts", "community prompts", "prompt search", "AI prompt library"], | |
| }) as Metadata | |
| async function getInitialPrompts(category?: string, search?: string, sort?: string) { | |
| try { | |
| const orderBy: Record<string, 'asc' | 'desc'>[] = [] | |
| switch (sort) { | |
| case 'recent': | |
| orderBy.push({ createdAt: 'desc' }) | |
| break | |
| case 'stars': | |
| orderBy.push({ starsCount: 'desc' }) | |
| break | |
| case 'runs': | |
| orderBy.push({ totalRuns: 'desc' }) | |
| break | |
| default: | |
| orderBy.push({ totalRuns: 'desc' }) | |
| } | |
| orderBy.push({ id: 'desc' }) | |
| const where: Record<string, unknown> = { | |
| visibility: 'public', | |
| } | |
| if (category) { | |
| where.category = category | |
| } | |
| if (search) { | |
| where.OR = [ | |
| { title: { contains: search, mode: 'insensitive' } }, | |
| { description: { contains: search, mode: 'insensitive' } }, | |
| ] | |
| } | |
| const prompts = await prisma.prompt.findMany({ | |
| where, | |
| include: { | |
| creator: { | |
| select: { | |
| name: true, | |
| username: true, | |
| image: true, | |
| }, | |
| }, | |
| }, | |
| orderBy, | |
| take: 12, | |
| }) | |
| return prompts | |
| } catch (error) { | |
| console.error('Explore page data fetch error:', error) | |
| return [] | |
| } | |
| } | |
| interface ExplorePageProps { | |
| searchParams: Promise<{ [key: string]: string | undefined }> | |
| } | |
| export default async function ExplorePage({ searchParams }: ExplorePageProps) { | |
| const params = await searchParams | |
| const initialPrompts = await getInitialPrompts( | |
| params.category, | |
| params.q, | |
| params.sort | |
| ) | |
| return ( | |
| <div className="container mx-auto px-4 py-8 max-w-7xl"> | |
| {/* Page Header */} | |
| <div className="mb-8"> | |
| <h1 className="text-3xl md:text-4xl font-serif font-medium mb-3"> | |
| Explore <span className="text-gradient italic">Prompts</span> | |
| </h1> | |
| <p className="text-muted-foreground text-lg"> | |
| Discover AI prompts created by the community | |
| </p> | |
| </div> | |
| {/* Client Component with Search/Filter */} | |
| <Suspense fallback={ | |
| <div className="flex items-center justify-center py-16"> | |
| <Loader2 className="h-8 w-8 animate-spin text-primary" /> | |
| </div> | |
| }> | |
| <ExploreClient initialPrompts={initialPrompts} /> | |
| </Suspense> | |
| </div> | |
| ) | |
| } | |