Skip to content

Commit 22090cc

Browse files
committed
[NEB-170] Nebula: Various UI changes (#6747)
<!-- start pr-codex --> ## PR-Codex overview This PR focuses on enhancing the user interface and experience of the `Nebula` app by updating text content, adjusting styles, and introducing a new `StyledMarkdownRenderer` component for better message rendering. ### Detailed summary - Updated text in `EmptyStateChatPageContent.tsx` and `ContextFilters.tsx` to reflect new terminology. - Changed section headings from `Context` to `Settings`. - Improved styling for various components, including `ChatSidebarLink` and buttons. - Introduced `StyledMarkdownRenderer` for consistent message formatting. - Adjusted scrollbar styles in `global.css`. - Modified button states and classes for better responsiveness and appearance. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 95a6c38 commit 22090cc

File tree

8 files changed

+95
-105
lines changed

8 files changed

+95
-105
lines changed

apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,11 @@ export function ChatPageContent(props: {
463463
</div>
464464
<aside className="hidden w-[360px] flex-col border-l bg-card pt-4 xl:flex">
465465
<div className="px-4">
466-
<h3 className="font-semibold text-lg tracking-tight">Context</h3>
466+
<h3 className="mb-0.5 font-semibold text-xl tracking-tight">
467+
Settings
468+
</h3>
467469
<p className="mb-5 text-muted-foreground text-sm">
468-
Provide context to Nebula for your prompts
470+
Modify Nebula to suit your needs
469471
</p>
470472
</div>
471473
<ContextFiltersForm

apps/dashboard/src/app/nebula-app/(app)/components/ChatSidebar.tsx

Lines changed: 35 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
"use client";
2-
import { ScrollShadow } from "@/components/ui/ScrollShadow/ScrollShadow";
32
import { Badge } from "@/components/ui/badge";
43
import { Button } from "@/components/ui/button";
54
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
6-
import {
7-
FileCode2Icon,
8-
MessageSquareShareIcon,
9-
MessagesSquareIcon,
10-
SquareDashedBottomCodeIcon,
11-
TextIcon,
12-
} from "lucide-react";
5+
import { ChevronRightIcon, FileCode2Icon, PlusIcon } from "lucide-react";
136
import Link from "next/link";
147
import type { TruncatedSessionInfo } from "../api/types";
158
import { useNewChatPageLink } from "../hooks/useNewChatPageLink";
@@ -29,54 +22,47 @@ export function ChatSidebar(props: {
2922
const newChatPage = useNewChatPageLink();
3023

3124
return (
32-
<div className="flex h-full flex-col p-2">
33-
<div className="flex items-center justify-start gap-3 p-2 lg:justify-between">
25+
<div className="flex h-full flex-col">
26+
<div className="flex items-center justify-start gap-3 p-4 lg:justify-between">
3427
<Link href="/" className="flex items-center gap-2">
3528
<NebulaIcon className="size-8 text-foreground" aria-label="Nebula" />
36-
<span className="font-semibold text-lg tracking-tight">
37-
Playground
38-
</span>
29+
<span className="font-semibold text-lg tracking-tight">Nebula</span>
3930
</Link>
4031

4132
<Badge variant="secondary" className="gap-1 py-1">
42-
Alpha
33+
Beta
4334
</Badge>
4435
</div>
4536

46-
<div className="h-4" />
37+
<div className="h-1" />
4738

48-
<div className="flex flex-col gap-2 px-2">
39+
<div className="flex flex-col gap-2 px-4">
4940
<Button asChild variant="outline" className="w-full gap-2 rounded-lg">
50-
<Link href={newChatPage}>New Chat</Link>
41+
<Link href={newChatPage}>
42+
<PlusIcon className="size-4" />
43+
New Chat
44+
</Link>
5145
</Button>
5246
</div>
5347

54-
<div className="h-3" />
55-
56-
<SidebarIconLink
57-
href="https://portal.thirdweb.com/nebula/api-reference"
58-
icon={FileCode2Icon}
59-
label="API Reference"
60-
target="_blank"
61-
/>
62-
63-
<SidebarIconLink
64-
href="/chat/history"
65-
icon={MessagesSquareIcon}
66-
label="All Chats"
67-
/>
48+
<div className="h-5" />
6849

6950
{sessionsToShow.length > 0 && (
70-
<ScrollShadow
71-
className="my-3 flex-1 border-t border-dashed pt-2"
72-
scrollableClassName="max-h-full"
73-
shadowColor="transparent"
74-
shadowClassName="z-10"
75-
>
51+
<div className="flex-1 overflow-auto border-t border-dashed p-2 pt-2">
52+
<div className="flex items-center justify-between px-2 py-3">
53+
<h3 className="text-muted-foreground text-xs">Recent Chats</h3>
54+
{sessionsToShow.length < sessions.length && (
55+
<Link
56+
href="/chat/history"
57+
className="flex items-center gap-1 rounded-full text-foreground text-xs hover:underline"
58+
>
59+
View All
60+
<ChevronRightIcon className="size-3.5 text-muted-foreground" />
61+
</Link>
62+
)}
63+
</div>
64+
7665
<div className="flex flex-col gap-1">
77-
<h3 className="px-2 py-3 text-muted-foreground text-xs">
78-
Recent Chats
79-
</h3>
8066
{sessionsToShow.map((session) => {
8167
return (
8268
<ChatSidebarLink
@@ -88,27 +74,13 @@ export function ChatSidebar(props: {
8874
);
8975
})}
9076
</div>
91-
</ScrollShadow>
77+
</div>
9278
)}
9379

94-
<div className="mb-3 border-y border-dashed py-3">
95-
<SidebarIconLink
96-
href="https://docs.google.com/forms/d/e/1FAIpQLSeM3fJRyywihRZUF1fiTNKEpJ_AzAcohRwXPpLr_3zxQ6W-tg/viewform?usp=sharing"
97-
icon={MessageSquareShareIcon}
98-
label="Take our quick survey!"
99-
target="_blank"
100-
/>
101-
102-
<SidebarIconLink
103-
href="https://portal.thirdweb.com/changelog"
104-
icon={TextIcon}
105-
label="Changelog"
106-
target="_blank"
107-
/>
108-
80+
<div className="mb-3 border-y border-dashed px-2 py-3">
10981
<SidebarIconLink
11082
href="https://portal.thirdweb.com/nebula"
111-
icon={SquareDashedBottomCodeIcon}
83+
icon={FileCode2Icon}
11284
label="Documentation"
11385
target="_blank"
11486
/>
@@ -130,13 +102,12 @@ function SidebarIconLink(props: {
130102
href: string;
131103
}) {
132104
return (
133-
<Button asChild variant="ghost">
134-
<Link
135-
href={props.href}
136-
target={props.target}
137-
className="!justify-start !px-3 w-full gap-2.5 rounded-lg text-left"
138-
prefetch={false}
139-
>
105+
<Button
106+
asChild
107+
variant="ghost"
108+
className="h-auto w-full justify-start gap-2.5 rounded-lg px-2 py-1.5 text-left text-sm"
109+
>
110+
<Link href={props.href} target={props.target} prefetch={false}>
140111
<props.icon className="size-4" />
141112
{props.label}
142113
</Link>

apps/dashboard/src/app/nebula-app/(app)/components/ChatSidebarLink.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export function ChatSidebarLink(props: {
5252
<Button
5353
asChild
5454
variant="ghost"
55-
className="!h-auto !w-full items-center justify-between px-2 text-left text-sm hover:bg-transparent"
55+
className="h-auto w-full items-center justify-between px-2 py-1.5 text-left text-sm hover:bg-transparent"
5656
>
5757
<NavLink href={`/chat/${props.sessionId}`} activeClassName="bg-muted">
5858
<span className="line-clamp-1 block truncate">{props.title}</span>
@@ -61,7 +61,7 @@ export function ChatSidebarLink(props: {
6161
<Popover>
6262
<PopoverTrigger asChild>
6363
<Button
64-
className="-translate-y-1/2 !bg-background absolute top-1/2 right-1 z-10 h-auto w-auto p-1.5 opacity-0 group-hover:opacity-100"
64+
className="-translate-y-1/2 absolute top-1/2 right-1 z-10 h-auto w-auto bg-accent p-1 opacity-0 hover:bg-zinc-300 group-hover:opacity-100 dark:hover:bg-zinc-700"
6565
variant="ghost"
6666
>
6767
<EllipsisIcon className="size-4" />

apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,9 @@ export function Chats(props: {
117117
{message.type === "user" ? (
118118
<div className="mt-6 flex justify-end">
119119
<div className="max-w-[80%] overflow-auto rounded-xl border bg-card px-4 py-2">
120-
<MarkdownRenderer
121-
skipHtml
122-
markdownText={message.text}
123-
code={{
124-
ignoreFormattingErrors: true,
125-
className: "bg-transparent",
126-
}}
127-
className="text-foreground [&>*:last-child]:mb-0"
128-
p={{ className: "text-foreground leading-normal" }}
129-
li={{ className: "text-foreground" }}
130-
inlineCode={{ className: "border-none" }}
120+
<StyledMarkdownRenderer
121+
text={message.text}
122+
isMessagePending={isMessagePending}
131123
/>
132124
</div>
133125
</div>
@@ -161,18 +153,9 @@ export function Chats(props: {
161153
<div className="min-w-0 grow">
162154
<ScrollShadow className="rounded-lg">
163155
{message.type === "assistant" ? (
164-
<MarkdownRenderer
165-
skipHtml
166-
markdownText={message.text}
167-
code={{
168-
disableCodeHighlight: isMessagePending,
169-
ignoreFormattingErrors: true,
170-
}}
171-
className="text-foreground [&>*:last-child]:mb-0"
172-
p={{
173-
className: "text-foreground",
174-
}}
175-
li={{ className: "text-foreground" }}
156+
<StyledMarkdownRenderer
157+
text={message.text}
158+
isMessagePending={isMessagePending}
176159
/>
177160
) : message.type === "error" ? (
178161
<div className="rounded-xl border bg-card px-4 py-2 text-destructive-text leading-normal">
@@ -332,3 +315,23 @@ function MessageActions(props: {
332315
</div>
333316
);
334317
}
318+
319+
function StyledMarkdownRenderer(props: {
320+
text: string;
321+
isMessagePending: boolean;
322+
}) {
323+
return (
324+
<MarkdownRenderer
325+
skipHtml
326+
markdownText={props.text}
327+
className="text-foreground [&>*:first-child]:mt-0 [&>*:first-child]:border-none [&>*:first-child]:pb-0 [&>*:last-child]:mb-0"
328+
code={{
329+
ignoreFormattingErrors: true,
330+
className: "bg-transparent",
331+
}}
332+
p={{ className: "text-foreground leading-normal" }}
333+
li={{ className: "text-foreground" }}
334+
inlineCode={{ className: "border-none" }}
335+
/>
336+
);
337+
}

apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ export default function ContextFiltersButton(props: {
6666
</DialogTrigger>
6767
<DialogContent className="overflow-hidden p-0">
6868
<DialogHeader className="px-6 pt-6 pb-1">
69-
<DialogTitle className="font-semibold text-xl">Context</DialogTitle>
69+
<DialogTitle className="font-semibold text-xl">Settings</DialogTitle>
7070
<DialogDescription className="text-muted-foreground">
71-
Provide context to Nebula for your prompts
71+
Modify Nebula to suit your needs
7272
</DialogDescription>
7373
</DialogHeader>
7474

@@ -198,7 +198,9 @@ export function ContextFiltersForm(props: {
198198
.filter(Boolean)
199199
.map(Number)}
200200
onChange={(values) => {
201-
form.setValue("chainIds", values.join(","));
201+
form.setValue("chainIds", values.join(","), {
202+
shouldDirty: true,
203+
});
202204
}}
203205
priorityChains={[
204206
1, // ethereum
@@ -251,13 +253,20 @@ export function ContextFiltersForm(props: {
251253
</DialogClose>
252254
)}
253255
<Button
254-
className="min-w-24 gap-2"
256+
className="min-w-24 gap-2 disabled:text-muted-foreground disabled:opacity-100"
255257
type="submit"
256258
size="sm"
257-
disabled={updateMutation.isPending}
259+
variant={
260+
props.modal
261+
? "default"
262+
: form.formState.isDirty
263+
? "default"
264+
: "outline"
265+
}
266+
disabled={updateMutation.isPending || !form.formState.isDirty}
258267
>
259268
{updateMutation.isPending && <Spinner className="size-4" />}
260-
Update Context
269+
Save
261270
</Button>
262271
</div>
263272
</form>

apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ export function EmptyStateChatPageContent(props: {
2323
</div>
2424
<div className="h-5" />
2525
<h1 className="px-4 text-center font-semibold text-3xl tracking-tight md:text-4xl">
26-
How can I help you <br className="max-sm:hidden" />
27-
with the blockchain today?
26+
How can I help you <br /> onchain today?
2827
</h1>
2928
<div className="h-5" />
3029
<div className="mx-auto max-w-[600px]">

apps/dashboard/src/components/contract-components/published-contract/markdown-renderer.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const MarkdownRenderer: React.FC<{
4949
<h2
5050
className={cn(
5151
commonHeadingClassName,
52-
"mb-4 border-border border-b text-3xl",
52+
"mb-3 border-border border-b text-xl md:text-2xl",
5353
)}
5454
{...cleanedProps(props)}
5555
/>
@@ -60,15 +60,18 @@ export const MarkdownRenderer: React.FC<{
6060
{...cleanedProps(props)}
6161
className={cn(
6262
commonHeadingClassName,
63-
"mt-8 mb-4 border-border border-b text-2xl",
63+
"mt-8 mb-3 border-border border-b text-lg md:text-xl",
6464
)}
6565
/>
6666
),
6767

6868
h3: (props) => (
6969
<h4
7070
{...cleanedProps(props)}
71-
className={cn(commonHeadingClassName, "mt-4 text-xl")}
71+
className={cn(
72+
commonHeadingClassName,
73+
"mt-4 text-base md:text-lg",
74+
)}
7275
/>
7376
),
7477

@@ -198,9 +201,7 @@ export const MarkdownRenderer: React.FC<{
198201
</li>
199202
),
200203
strong(props) {
201-
return (
202-
<strong className="font-semibold" {...cleanedProps(props)} />
203-
);
204+
return <strong className="font-medium" {...cleanedProps(props)} />;
204205
},
205206
}}
206207
>

apps/dashboard/src/global.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,8 @@ body {
200200
--chakra-zIndices-overlay: 50;
201201
--chakra-colors-chakra-border-color: hsl(var(--border));
202202
}
203+
204+
* {
205+
scrollbar-width: thin;
206+
scrollbar-color: hsl(var(--muted)) transparent;
207+
}

0 commit comments

Comments
 (0)