diff --git a/src/app/api/listings/route.ts b/src/app/api/listings/route.ts new file mode 100644 index 0000000..fa62dfd --- /dev/null +++ b/src/app/api/listings/route.ts @@ -0,0 +1,36 @@ +import { NextRequest, NextResponse } from 'next/server'; +import prisma from '@/app/api/utils/prisma'; + +export async function GET(req: NextRequest, res: NextResponse) { + let assistants = await prisma.assistant.findMany({ + where: { + published: true + }, + select: { + id: true, + object: true, + avatar: true, + profile: true, + modelId: true, + published: true, + authenticatedUsersOnly: true, + }, + }); + let assistantsCollection = assistants.map((assistant) => { + if (assistant.object) { + // @ts-ignore + assistant.object.profile = assistant.profile; + // @ts-ignore + assistant.object.modelId = assistant.modelId; + // @ts-ignore + assistant.object.published = assistant.published; + // @ts-ignore + assistant.object.avatar = assistant.avatar; + // @ts-ignore + assistant.object.authenticatedUsersOnly = + assistant.authenticatedUsersOnly; + } + return assistant.object; + }); + return Response.json(assistantsCollection, { status: 200 }); +} \ No newline at end of file diff --git a/src/app/listings/ListingCard.tsx b/src/app/listings/ListingCard.tsx new file mode 100644 index 0000000..32c3f63 --- /dev/null +++ b/src/app/listings/ListingCard.tsx @@ -0,0 +1,42 @@ +'use client' + +import { Assistant } from '@/app/types/assistant'; +import { Avatar, Button, Card } from 'flowbite-react'; +import { getImageHash } from '@/app/utils/hash'; +import React from 'react'; + +export interface ListingCardProps { + listing: Assistant +} + +export default function ListingCard(props:ListingCardProps) { + return +
+ +
+
+ {props.listing.name} +
+

+ {props.listing.description} +

+

+ By @santthosh +

+
+
+
+} \ No newline at end of file diff --git a/src/app/listings/client.ts b/src/app/listings/client.ts new file mode 100644 index 0000000..c1d3872 --- /dev/null +++ b/src/app/listings/client.ts @@ -0,0 +1,27 @@ +import useSWR from 'swr'; +import { fetcher } from '@/app/utils/fetcher'; +import { useMemo } from 'react'; +import { Assistant } from '@/app/types/assistant'; + +export function useGetListings() { + let { data, isLoading, error, isValidating, mutate } = useSWR('/api/listings', + fetcher, + { + revalidateIfStale: true, + revalidateOnFocus: false, + revalidateOnReconnect: false, + } + ); + + return useMemo( + () => ({ + listings: data as Assistant[], + listingsLoading: isLoading, + listingsError: error, + listingsValidating: isValidating, + listingsEmpty: !isLoading && !data?.length, + mutate: mutate, + }), + [data, error, isLoading, isValidating, mutate] + ); + } diff --git a/src/app/listings/layout.tsx b/src/app/listings/layout.tsx new file mode 100644 index 0000000..01d608a --- /dev/null +++ b/src/app/listings/layout.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Header } from '@/components/Header'; +import { Toaster } from 'react-hot-toast'; +import { PageFooter } from '@/components/Footer'; + +export default function ListingsLayout({ + children, + }: { + children: React.ReactNode; +}) { + return ( +
+
+ + {children} + +
+ ); +} diff --git a/src/app/listings/page.tsx b/src/app/listings/page.tsx new file mode 100644 index 0000000..8a149d8 --- /dev/null +++ b/src/app/listings/page.tsx @@ -0,0 +1,31 @@ +'use client' + +import React, { useEffect } from 'react'; +import { useGetListings } from '@/app/listings/client'; +import { Button, Spinner } from 'flowbite-react'; +import ListingCard from '@/app/listings/ListingCard'; + +export default function Listings() { + let { listingsLoading, listings, listingsEmpty, mutate } = useGetListings(); + + useEffect(() => {}, [listings]); + + if (listingsLoading) { + return
+ +
+ } + + return
+
+ { + listings && listings.length > 0 ? + listings.map((listing) => { + return
{console.log(listing.id)}}> + +
+ }) : <> + } +
+
; +} \ No newline at end of file