Skip to content

Commit e6b861f

Browse files
feat(history): add triggerOnly prop to History component for conditional rendering
1 parent a1c0302 commit e6b861f

File tree

2 files changed

+192
-63
lines changed

2 files changed

+192
-63
lines changed

components/custom/history.tsx

Lines changed: 146 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
SheetTitle,
4545
} from "../ui/sheet";
4646

47-
export const History = ({ user }: { user: User | undefined }) => {
47+
export const History = ({ user, triggerOnly = false }: { user: User | undefined; triggerOnly?: boolean }) => {
4848
const { id } = useParams();
4949
const pathname = usePathname();
5050

@@ -85,8 +85,148 @@ export const History = ({ user }: { user: User | undefined }) => {
8585
setShowDeleteDialog(false);
8686
};
8787

88+
if (triggerOnly) {
89+
return (
90+
<>
91+
<Button
92+
variant="outline"
93+
className="p-1.5 h-fit"
94+
onClick={() => {
95+
setIsHistoryVisible(true);
96+
}}
97+
>
98+
<MenuIcon />
99+
</Button>
100+
<Sheet
101+
open={isHistoryVisible}
102+
onOpenChange={(state) => {
103+
setIsHistoryVisible(state);
104+
}}
105+
>
106+
<SheetContent side="right" className="p-3 w-80 bg-muted">
107+
<SheetHeader>
108+
<VisuallyHidden.Root>
109+
<SheetTitle className="text-left">History</SheetTitle>
110+
<SheetDescription className="text-left">
111+
{history === undefined ? "loading" : history.length} chats
112+
</SheetDescription>
113+
</VisuallyHidden.Root>
114+
</SheetHeader>
115+
{/* ...existing code for history list... */}
116+
<div className="mt-10 flex flex-col">
117+
{user && (
118+
<Button
119+
className="font-normal text-sm flex flex-row justify-between text-white"
120+
asChild
121+
>
122+
<Link href="/">
123+
<div>Start a new chat</div>
124+
<PencilEditIcon size={14} />
125+
</Link>
126+
</Button>
127+
)}
128+
<div className="flex flex-col overflow-y-scroll p-1 h-[calc(100dvh-124px)]">
129+
{/* ...existing code for chat list, loading, empty, etc... */}
130+
{!user ? (
131+
<div className="text-zinc-500 h-dvh w-full flex flex-row justify-center items-center text-sm gap-2">
132+
<InfoIcon />
133+
<div>Login to save and revisit previous chats!</div>
134+
</div>
135+
) : null}
136+
{!isLoading && history?.length === 0 && user ? (
137+
<div className="text-zinc-500 h-dvh w-full flex flex-row justify-center items-center text-sm gap-2">
138+
<InfoIcon />
139+
<div>No chats found</div>
140+
</div>
141+
) : null}
142+
{isLoading && user ? (
143+
<div className="flex flex-col">
144+
{[44, 32, 28, 52].map((item) => (
145+
<div key={item} className="p-2 my-[2px]">
146+
<div
147+
className={`w-${item} h-[20px] rounded-md bg-zinc-200 dark:bg-zinc-600 animate-pulse`}
148+
/>
149+
</div>
150+
))}
151+
</div>
152+
) : null}
153+
{history &&
154+
history.map((chat) => (
155+
<div
156+
key={chat.id}
157+
className={cx(
158+
"flex flex-row items-center gap-6 hover:bg-zinc-200 dark:hover:bg-zinc-700 rounded-md pr-2",
159+
{ "bg-zinc-200 dark:bg-zinc-700": chat.id === id },
160+
)}
161+
>
162+
<Button
163+
variant="ghost"
164+
className={cx(
165+
"hover:bg-zinc-200 dark:hover:bg-zinc-700 justify-between p-0 text-sm font-normal flex flex-row items-center gap-2 pr-2 w-full transition-none",
166+
)}
167+
asChild
168+
>
169+
<Link
170+
href={`/chat/${chat.id}`}
171+
className="text-ellipsis overflow-hidden text-left py-2 pl-2 rounded-lg outline-zinc-900"
172+
>
173+
{getTitleFromChat(chat)}
174+
</Link>
175+
</Button>
176+
<DropdownMenu modal={true}>
177+
<DropdownMenuTrigger asChild>
178+
<Button
179+
className="p-0 h-fit font-normal text-zinc-500 transition-none hover:bg-zinc-200 dark:hover:bg-zinc-700"
180+
variant="ghost"
181+
>
182+
<MoreHorizontalIcon />
183+
</Button>
184+
</DropdownMenuTrigger>
185+
<DropdownMenuContent side="left" className="z-[60]">
186+
<DropdownMenuItem asChild>
187+
<Button
188+
className="flex flex-row gap-2 items-center justify-start w-full h-fit font-normal p-1.5 rounded-sm"
189+
variant="ghost"
190+
onClick={() => {
191+
setDeleteId(chat.id);
192+
setShowDeleteDialog(true);
193+
}}
194+
>
195+
<TrashIcon />
196+
<div>Delete</div>
197+
</Button>
198+
</DropdownMenuItem>
199+
</DropdownMenuContent>
200+
</DropdownMenu>
201+
</div>
202+
))}
203+
</div>
204+
</div>
205+
</SheetContent>
206+
</Sheet>
207+
<AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
208+
<AlertDialogContent>
209+
<AlertDialogHeader>
210+
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
211+
<AlertDialogDescription>
212+
This action cannot be undone. This will permanently delete your
213+
chat and remove it from our servers.
214+
</AlertDialogDescription>
215+
</AlertDialogHeader>
216+
<AlertDialogFooter>
217+
<AlertDialogCancel>Cancel</AlertDialogCancel>
218+
<AlertDialogAction onClick={handleDelete}>
219+
Continue
220+
</AlertDialogAction>
221+
</AlertDialogFooter>
222+
</AlertDialogContent>
223+
</AlertDialog>
224+
</>
225+
);
226+
}
227+
// ...existing code for full history panel (if not triggerOnly)...
88228
return (
89-
<>
229+
<div className="fixed top-4 right-4 z-50 flex flex-row justify-end w-full">
90230
<Button
91231
variant="outline"
92232
className="p-1.5 h-fit"
@@ -96,14 +236,13 @@ export const History = ({ user }: { user: User | undefined }) => {
96236
>
97237
<MenuIcon />
98238
</Button>
99-
100239
<Sheet
101240
open={isHistoryVisible}
102241
onOpenChange={(state) => {
103242
setIsHistoryVisible(state);
104243
}}
105244
>
106-
<SheetContent side="left" className="p-3 w-80 bg-muted">
245+
<SheetContent side="right" className="p-3 w-80 bg-muted">
107246
<SheetHeader>
108247
<VisuallyHidden.Root>
109248
<SheetTitle className="text-left">History</SheetTitle>
@@ -112,17 +251,7 @@ export const History = ({ user }: { user: User | undefined }) => {
112251
</SheetDescription>
113252
</VisuallyHidden.Root>
114253
</SheetHeader>
115-
116-
<div className="text-sm flex flex-row items-center justify-between">
117-
<div className="flex flex-row gap-2">
118-
<div className="dark:text-zinc-300">History</div>
119-
120-
<div className="dark:text-zinc-400 text-zinc-500">
121-
{history === undefined ? "loading" : history.length} chats
122-
</div>
123-
</div>
124-
</div>
125-
254+
{/* ...existing code for history list... */}
126255
<div className="mt-10 flex flex-col">
127256
{user && (
128257
<Button
@@ -135,22 +264,20 @@ export const History = ({ user }: { user: User | undefined }) => {
135264
</Link>
136265
</Button>
137266
)}
138-
139267
<div className="flex flex-col overflow-y-scroll p-1 h-[calc(100dvh-124px)]">
268+
{/* ...existing code for chat list, loading, empty, etc... */}
140269
{!user ? (
141270
<div className="text-zinc-500 h-dvh w-full flex flex-row justify-center items-center text-sm gap-2">
142271
<InfoIcon />
143272
<div>Login to save and revisit previous chats!</div>
144273
</div>
145274
) : null}
146-
147275
{!isLoading && history?.length === 0 && user ? (
148276
<div className="text-zinc-500 h-dvh w-full flex flex-row justify-center items-center text-sm gap-2">
149277
<InfoIcon />
150278
<div>No chats found</div>
151279
</div>
152280
) : null}
153-
154281
{isLoading && user ? (
155282
<div className="flex flex-col">
156283
{[44, 32, 28, 52].map((item) => (
@@ -162,7 +289,6 @@ export const History = ({ user }: { user: User | undefined }) => {
162289
))}
163290
</div>
164291
) : null}
165-
166292
{history &&
167293
history.map((chat) => (
168294
<div
@@ -186,7 +312,6 @@ export const History = ({ user }: { user: User | undefined }) => {
186312
{getTitleFromChat(chat)}
187313
</Link>
188314
</Button>
189-
190315
<DropdownMenu modal={true}>
191316
<DropdownMenuTrigger asChild>
192317
<Button
@@ -218,7 +343,6 @@ export const History = ({ user }: { user: User | undefined }) => {
218343
</div>
219344
</SheetContent>
220345
</Sheet>
221-
222346
<AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
223347
<AlertDialogContent>
224348
<AlertDialogHeader>
@@ -236,6 +360,6 @@ export const History = ({ user }: { user: User | undefined }) => {
236360
</AlertDialogFooter>
237361
</AlertDialogContent>
238362
</AlertDialog>
239-
</>
363+
</div>
240364
);
241365
};

components/custom/navbar.tsx

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,58 +21,63 @@ export const Navbar = async () => {
2121
<>
2222
<div className="bg-background absolute top-0 left-0 w-dvw py-2 px-3 justify-between flex flex-row items-center z-30">
2323
<div className="flex flex-row gap-3 items-center">
24-
<History user={session?.user} />
2524
<div className="flex flex-row gap-2 items-center">
2625
<Image
2726
src="/images/italia-rail.png"
2827
height={200}
2928
width={200}
3029
alt="Italia Rail logo"
3130
/>
32-
3331
</div>
3432
</div>
3533

36-
{session ? (
37-
<DropdownMenu>
38-
<DropdownMenuTrigger asChild>
39-
<Button
40-
className="py-1.5 px-2 h-fit font-normal"
41-
variant="secondary"
42-
>
43-
{session.user?.email}
44-
</Button>
45-
</DropdownMenuTrigger>
46-
<DropdownMenuContent align="end">
47-
<DropdownMenuItem>
48-
<ThemeToggle />
49-
</DropdownMenuItem>
50-
<DropdownMenuItem className="p-1 z-50">
51-
<form
52-
className="w-full"
53-
action={async () => {
54-
"use server";
55-
56-
await signOut({
57-
redirectTo: "/",
58-
});
59-
}}
60-
>
61-
<button
62-
type="submit"
63-
className="w-full text-left px-1 py-0.5 text-red-500"
34+
<div className="flex flex-row gap-2 items-center">
35+
{session ? (
36+
<>
37+
<DropdownMenu>
38+
<DropdownMenuTrigger asChild>
39+
<Button
40+
className="py-1.5 px-2 h-fit font-normal rounded-full bg-emerald-600 text-white w-8 h-8 flex items-center justify-center text-lg"
41+
variant="secondary"
6442
>
65-
Sign out
66-
</button>
67-
</form>
68-
</DropdownMenuItem>
69-
</DropdownMenuContent>
70-
</DropdownMenu>
71-
) : (
72-
<Button className="py-1.5 px-2 h-fit font-normal text-white" asChild>
73-
<Link href="/login">Login</Link>
74-
</Button>
75-
)}
43+
{session.user?.email?.slice(0, 2).toUpperCase()}
44+
</Button>
45+
</DropdownMenuTrigger>
46+
<DropdownMenuContent align="end">
47+
<DropdownMenuItem>
48+
{session.user?.email}
49+
</DropdownMenuItem>
50+
<DropdownMenuItem>
51+
<ThemeToggle />
52+
</DropdownMenuItem>
53+
<DropdownMenuItem className="p-1 z-50">
54+
<form
55+
className="w-full"
56+
action={async () => {
57+
"use server";
58+
await signOut({
59+
redirectTo: "/",
60+
});
61+
}}
62+
>
63+
<button
64+
type="submit"
65+
className="w-full text-left px-1 py-0.5 text-red-500"
66+
>
67+
Sign out
68+
</button>
69+
</form>
70+
</DropdownMenuItem>
71+
</DropdownMenuContent>
72+
</DropdownMenu>
73+
<History user={session?.user} triggerOnly />
74+
</>
75+
) : (
76+
<Button className="py-1.5 px-2 h-fit font-normal text-white" asChild>
77+
<Link href="/login">Login</Link>
78+
</Button>
79+
)}
80+
</div>
7681
</div>
7782
</>
7883
);

0 commit comments

Comments
 (0)