Skip to content

Commit 8219716

Browse files
authored
[masterbots.ai] feat: update ChatChatbotDetails (#314)
* feat: new bot profile - chat * chore: dev comments * chore: white bg bot avatar * feat: add skeleton bot profile
1 parent a0ca3b8 commit 8219716

File tree

7 files changed

+178
-75
lines changed

7 files changed

+178
-75
lines changed

apps/masterbots.ai/components/routes/browse/browse-list.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
*/
2222

2323
import BrowseListItem from '@/components/routes/browse/browse-list-item'
24-
import { ThreadItemSkeleton } from '@/components/routes/browse/skeletons/browse-skeletons'
25-
import { BrowseListSkeleton } from '@/components/routes/browse/skeletons/browse-list-skeleton'
24+
import { ThreadItemSkeleton } from '@/components/shared/skeletons/browse-skeletons'
25+
import { BrowseListSkeleton } from '@/components/shared/skeletons/browse-list-skeleton'
2626
import { useBrowse } from '@/lib/hooks/use-browse'
2727
import { useSidebar } from '@/lib/hooks/use-sidebar'
2828
import { searchThreadContent } from '@/lib/search'

apps/masterbots.ai/components/routes/chat/chat-chatbot-details.tsx

Lines changed: 130 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,166 @@
1-
//* Component for displaying details of the selected chatbot
2-
3-
'use client'
4-
5-
import { Separator } from '@/components/ui/separator'
1+
import { useSession } from 'next-auth/react'
62
import { useSidebar } from '@/lib/hooks/use-sidebar'
73
import { useThread } from '@/lib/hooks/use-thread'
4+
import { useParams } from 'next/navigation'
5+
import { useState, useEffect } from 'react'
86
import { getCategory, getThreads } from '@/services/hasura'
9-
import { useSession } from 'next-auth/react'
107
import Image from 'next/image'
11-
import { useParams } from 'next/navigation'
12-
import { useEffect, useState } from 'react'
8+
import { Button } from '@/components/ui/button'
9+
import { MessageSquare, MessageCircle, Users } from 'lucide-react'
10+
import { cn } from '@/lib/utils'
11+
import { toSlug } from 'mb-lib'
12+
import { ChatChatbotDetailsSkeleton } from '@/components/shared/skeletons/chat-chatbot-details-skeleton'
13+
14+
/**
15+
* Displays detailed information about a chatbot or welcome message in the Masterbots application.
16+
* It serves as both a welcome screen for new users and a details card for specific chatbots.
17+
*
18+
* @features
19+
* - Displays welcome message or chatbot information
20+
* - Shows chatbot avatar with customizable border colors for light/dark modes
21+
* - Presents thread count and follower statistics
22+
* - Provides quick actions (Follow, New Chat)
23+
* - Fully responsive design with mobile-first approach
24+
* - Supports both light and dark themes
25+
*/
1326

1427
export default function ChatChatbotDetails({ page }: { page?: string }) {
15-
const { data: session } = useSession() //* Retrieves session data using next-auth
16-
const { activeCategory, activeChatbot } = useSidebar() //* Retrieves active category and chatbot from sidebar state
17-
const { randomChatbot } = useThread() //* Retrieves a random chatbot from thread state
18-
const [threadNum, setThreadNum] = useState<number>(0) //* Stores the number of threads
19-
const [categoryName, setCategoryName] = useState<string>('') //* Stores the name of the active category
20-
// get current url params use UseParams hook from next/router to get the current url params and use it to fetch the data
21-
const { slug } = useParams()
22-
23-
//* Fetches the number of threads for the active category and user
28+
const { data: session } = useSession()
29+
const { activeCategory, activeChatbot } = useSidebar()
30+
const { randomChatbot } = useThread()
31+
const [threadNum, setThreadNum] = useState<number>(0)
32+
const [categoryName, setCategoryName] = useState<string>('')
33+
const { slug } = useParams()
34+
35+
36+
if (status === "loading") return <ChatChatbotDetailsSkeleton />
37+
2438
const getThreadNum = async () => {
2539
if (!session?.user) return
26-
2740
const threads = await getThreads({
2841
jwt: session?.user?.hasuraJwt as string,
2942
categoryId: activeCategory,
3043
userId: session?.user.id as string
3144
})
32-
setThreadNum(threads?.length ?? 0) //* Updates thread number state
45+
setThreadNum(threads?.length ?? 0)
3346
}
3447

35-
//* Fetches the name of the active category
3648
const getCategoryName = async () => {
37-
const category = await getCategory({ categoryId: activeCategory as number }) //* Retrieves category details
38-
setCategoryName(category.name) //* Updates category name state
49+
const category = await getCategory({ categoryId: activeCategory as number })
50+
setCategoryName(category.name)
3951
}
4052

41-
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
53+
// eslint-disable-next-line react-hooks/rules-of-hooks
4254
useEffect(() => {
43-
//* Effect to fetch thread number or category name based on active category
4455
if (!activeCategory) {
45-
getThreadNum() //* Fetch thread number if no category is active
56+
getThreadNum()
4657
} else {
4758
getCategoryName()
4859
}
49-
// eslint-disable-next-line react-hooks/exhaustive-deps
5060
}, [activeCategory, activeChatbot, session?.user])
5161

62+
const botName = activeChatbot?.name || 'BuildBot'
63+
5264
return (
53-
<div className="h-[calc(100vh-196px)] flex items-center justify-center">
54-
<div
55-
className="dark:bg-[#09090B] bg-white rounded-lg md:w-[600px] w-[85%]
56-
flex flex-col gap-[10px] relative font-mono"
57-
>
58-
<div className="w-[70%] flex flex-col gap-[10px] px-[24px] pt-[24px]">
59-
<div className="text-2xl font-black">
60-
{ page != 'profile' ? (activeChatbot ? activeChatbot?.name : 'Welcome to Masterbots!') : `Browse ${slug}'s threads`}
65+
<div className="h-[calc(100vh-196px)] flex items-center justify-center -translate-y-8">
66+
<div className="dark:bg-[#09090B] bg-white w-[85%] md:w-[600px] rounded-xl text-white relative">
67+
{/* Card Header */}
68+
<div className="px-4 pt-4 md:px-6 md:pt-6">
69+
<div className="text-base font-bold leading-relaxed md:text-2xl text-zinc-950 dark:text-gray-300">
70+
Welcome to Masterbots!
6171
</div>
62-
<Separator className="bg-gray-300 dark:bg-mirage" />
63-
<div className="grow flex flex-col justify-between min-h-[137px]">
64-
{
65-
page === 'profile' && (
66-
<div className="text-xl font-semibold">
67-
Select category or bot to see or browse more threads from {slug}
68-
</div>
69-
)
70-
}
71-
{/* <div className="text-xl font-semibold">
72-
{ page != 'profile' && (activeChatbot
73-
? categoryName
74-
: activeCategory
75-
? `You are on the ${categoryName} category. Please select one of the bots on the sidebar to start a conversation.`
76-
: 'Please select one of the categories and a bot on the sidebar to start a conversation.')}
77-
</div> */}
78-
<div className="text-base gap-[8px] flex flex-col pb-[8px]">
79-
{/* biome-ignore lint/complexity/useOptionalChain: <explanation> */}
80-
{activeChatbot && activeChatbot?.description ? (
81-
<div className="font-medium">{activeChatbot.description}</div>
82-
) : (
83-
''
72+
</div>
73+
74+
{/* Separator Line - Extended to edges */}
75+
<div className="h-[3px] bg-zinc-200 dark:bg-slate-800 mt-6 relative">
76+
{/* Floating Avatar - Responsive sizing */}
77+
<div className="absolute right-4 -top-10 md:right-6 md:-top-12">
78+
<div
79+
className={cn(
80+
'size-20 md:size-32 rounded-full p-2 md:p-2.5 relative', // Smaller size on mobile
81+
'bg-zinc-200 dark:bg-black',
82+
'ring-2 ring-[#be16e8] dark:ring-[#82e46a]'
8483
)}
85-
<div className="font-light">
86-
Threads made:{' '}
87-
<span className="text-[#71717A]">
88-
{activeChatbot
89-
? (activeChatbot?.threads?.length ?? 0)
90-
: threadNum}
84+
>
85+
<Image
86+
src={activeChatbot?.avatar || randomChatbot?.avatar || ''}
87+
alt={`${botName} avatar`}
88+
height={128}
89+
width={128}
90+
className="object-cover rounded-full"
91+
/>
92+
</div>
93+
</div>
94+
</div>
95+
96+
{/* Description with right margin to avoid avatar overlap */}
97+
<div className="p-2 px-4 mr-2 md:p-3 md:px-6 md:mr-4">
98+
<p className="pr-24 text-sm font-normal text-justify md:pr-32 md:text-base text-zinc-500 dark:text-zinc-500">
99+
Here you can create new threads and share them to your network!
100+
Navigate with the sidebar and pick any bot of your interest.
101+
</p>
102+
</div>
103+
104+
{/* Card Content */}
105+
<div className="px-4 pb-4 md:px-6 md:pb-6 flex flex-col items-center justify-start gap-1.5">
106+
<div className="mb-3 text-center md:mb-4">
107+
<h2 className="text-lg md:text-2xl font-semibold leading-[34.08px] text-zinc-950 dark:text-gray-300">
108+
Your Journey Begins Here!
109+
</h2>
110+
<p className="text-base font-semibold leading-relaxed md:text-lg text-zinc-500 dark:text-zinc-500">
111+
Try and start with: {botName}
112+
</p>
113+
</div>
114+
115+
<div className="flex flex-col items-center w-full gap-3">
116+
<div className="flex items-center justify-center gap-4 md:gap-6">
117+
<div className="flex items-center gap-1">
118+
<MessageSquare className="w-4 h-4 text-zinc-950 dark:text-gray-300" />
119+
<span className="text-xs font-normal leading-tight md:text-sm text-zinc-950 dark:text-gray-300">
120+
Threads:{' '}
121+
<span className="text-zinc-500 dark:text-zinc-500">
122+
{activeChatbot
123+
? (activeChatbot?.threads?.length ?? 0)
124+
: threadNum}
125+
</span>
91126
</span>
92127
</div>
128+
129+
<div className="flex items-center gap-2 md:gap-3">
130+
<div className="flex items-center gap-1">
131+
<Users className="w-4 h-4 text-zinc-950 dark:text-gray-300" />
132+
<span className="text-xs font-normal leading-tight md:text-sm text-zinc-950 dark:text-gray-300">
133+
Followers:{' '}
134+
<span className="text-zinc-500 dark:text-zinc-500">
135+
3.2k
136+
</span>
137+
</span>
138+
</div>
139+
140+
<Button
141+
variant="outline"
142+
size="sm"
143+
className="text-xs md:text-sm border-zinc-200 dark:border-zinc-100/50 text-zinc-500 dark:text-zinc-500"
144+
>
145+
Follow
146+
</Button>
147+
</div>
93148
</div>
149+
150+
<Button
151+
className={cn(
152+
'w-auto px-4 md:px-6 py-2 text-sm md:text-base',
153+
'bg-[#be16e8] hover:bg-[#be16e8]/90',
154+
'dark:bg-[#82e46a] dark:hover:bg-[#82e46a]/90',
155+
'text-white dark:text-zinc-950',
156+
'leading-none'
157+
)}
158+
>
159+
<MessageCircle className="mr-2 size-4" />
160+
New Chat With {botName}
161+
</Button>
94162
</div>
95163
</div>
96-
<div className="size-24 absolute border-4 border-[#388DE2] right-0 top-0 translate-x-1/4 rounded-full translate-y-1/4 dark:bg-[#131316] bg-white">
97-
<Image
98-
className="transition-opacity duration-300 rounded-full select-none size-full ring-1 ring-zinc-100/10 hover:opacity-80"
99-
src={activeChatbot?.avatar || randomChatbot?.avatar || ''}
100-
alt={activeChatbot?.avatar || randomChatbot?.avatar || 'ChatAvatar'}
101-
height={108}
102-
width={108}
103-
/>
104-
</div>
105164
</div>
106165
</div>
107166
)

apps/masterbots.ai/components/shared/no-results-card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
CardContent
77
} from '@/components/ui/card'
88
import { SearchX, Filter } from 'lucide-react'
9-
import { NoResultsSkeleton } from '../routes/browse/skeletons/no-results-skeleton'
9+
import { NoResultsSkeleton } from './skeletons/no-results-skeleton'
1010

1111
interface NoResultsProps {
1212
searchTerm?: string

apps/masterbots.ai/components/routes/browse/skeletons/browse-list-skeleton.tsx renamed to apps/masterbots.ai/components/shared/skeletons/browse-list-skeleton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {ThreadItemSkeleton} from '@/components/routes/browse/skeletons/browse-skeletons';
1+
import {ThreadItemSkeleton} from '@/components/shared/skeletons/browse-skeletons';
22

33
export function BrowseListSkeleton({ count = 3 }: { count?: number }) {
44
return (

apps/masterbots.ai/components/routes/browse/skeletons/browse-skeletons.tsx renamed to apps/masterbots.ai/components/shared/skeletons/browse-skeletons.tsx

File renamed without changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Skeleton } from "@/components/ui/skeleton"
2+
3+
export function ChatChatbotDetailsSkeleton() {
4+
return (
5+
<div className="h-[calc(100vh-196px)] flex items-center justify-center -translate-y-8">
6+
<div className="dark:bg-[#09090B] bg-white w-[85%] md:w-[600px] rounded-xl text-white relative">
7+
{/* Card Header */}
8+
<div className="px-4 pt-4 md:px-6 md:pt-6">
9+
<Skeleton className="w-48 h-8" />
10+
</div>
11+
12+
{/* Separator Line with Avatar */}
13+
<div className="h-[3px] bg-zinc-200 dark:bg-slate-800 mt-6 relative">
14+
<div className="absolute right-4 -top-10 md:right-6 md:-top-12">
15+
<Skeleton className="rounded-full size-20 md:size-32" />
16+
</div>
17+
</div>
18+
19+
{/* Description */}
20+
<div className="p-2 px-4 mr-2 md:p-3 md:px-6 md:mr-4">
21+
<Skeleton className="h-16 w-[80%]" />
22+
</div>
23+
24+
{/* Card Content */}
25+
<div className="px-4 pb-4 md:px-6 md:pb-6 flex flex-col items-center justify-start gap-1.5">
26+
<div className="w-full mb-3 text-center md:mb-4">
27+
<Skeleton className="w-48 h-8 mx-auto mb-2" />
28+
<Skeleton className="h-6 mx-auto w-36" />
29+
</div>
30+
31+
<div className="flex flex-col items-center w-full gap-3">
32+
<div className="flex items-center justify-center gap-4 md:gap-6">
33+
<Skeleton className="w-24 h-6" />
34+
<Skeleton className="w-32 h-6" />
35+
<Skeleton className="w-20 h-8" />
36+
</div>
37+
38+
<Skeleton className="w-48 h-10" />
39+
</div>
40+
</div>
41+
</div>
42+
</div>
43+
)
44+
}

apps/masterbots.ai/components/routes/browse/skeletons/no-results-skeleton.tsx renamed to apps/masterbots.ai/components/shared/skeletons/no-results-skeleton.tsx

File renamed without changes.

0 commit comments

Comments
 (0)