Skip to content

Commit

Permalink
#93 Basic Listing Card functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
santthosh committed Jul 2, 2024
1 parent ff41dc9 commit df50794
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/app/api/listings/route.ts
Original file line number Diff line number Diff line change
@@ -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 });
}
42 changes: 42 additions & 0 deletions src/app/listings/ListingCard.tsx
Original file line number Diff line number Diff line change
@@ -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 <Card className={ 'w-96 h-42 min-w-max min-h-max bg-gray-100' }
horizontal>
<div className="grid grid-flow-col gap-4">
<Avatar
img={
props.listing.avatar
? props.listing.avatar
: '/images/people/avatar/' +
getImageHash(props.listing.id) +
'.jpg'
}
alt='avatar'
size='lg'
rounded
color='success'
/>
<div className={'flex flex-col gap-1'}>
<h6 className="text-sm font-bold tracking-tight text-gray-900 dark:text-white max-h-8 overflow-auto">
{props.listing.name}
</h6>
<p className="text-xs font-normal text-gray-700 dark:text-gray-400 max-w-60 max-h-8 overflow-auto">
{props.listing.description}
</p>
<p className="text-xs font-semi-bold text-gray-400 dark:text-gray-400 max-w-60">
By @santthosh
</p>
</div>
</div>
</Card>
}
27 changes: 27 additions & 0 deletions src/app/listings/client.ts
Original file line number Diff line number Diff line change
@@ -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]
);
}
19 changes: 19 additions & 0 deletions src/app/listings/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className={'bg-gray-50 dark:bg-gray-900'}>
<Header />
<Toaster position='top-center' />
{children}
<PageFooter />
</div>
);
}
31 changes: 31 additions & 0 deletions src/app/listings/page.tsx
Original file line number Diff line number Diff line change
@@ -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 <div className='bg-grey flex h-[calc(100vh-100px)] items-center justify-center '>
<Spinner />
</div>
}

return <div className={'m-4 min-h-[calc(100vh-100px)] items-center justify-center'}>
<div className={'flex flex-wrap items-center justify-center gap-4'}>
{
listings && listings.length > 0 ?
listings.map((listing) => {
return <div key={listing.id} className={'flex w-96 h-42 col-span-1 min-w-max'} onClick={() => {console.log(listing.id)}}>
<ListingCard listing={listing}></ListingCard>
</div>
}) : <></>
}
</div>
</div>;
}

0 comments on commit df50794

Please sign in to comment.