Skip to content

Commit 52d888c

Browse files
committed
feat(dashboard addon features and enhancements) 🚀: Implement StickyDynamicNav component with collapsable and resizable panels for navigation, mail list, and mail display so that one can see displayed important stuffs like mail right on orders and can reply right from dashboard itself , on orders , products or any other dashboard page . Includes various UI elements, icons, and dynamic layout options for an improved mail client interface.
1 parent 6183b61 commit 52d888c

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

‎components/dynamic-sticky-nav.tsx

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
'use client';
2+
3+
import {
4+
AlertCircle,
5+
Archive,
6+
File,
7+
Inbox,
8+
MessagesSquare,
9+
PenBox,
10+
Search,
11+
Send,
12+
ShoppingCart,
13+
Trash2,
14+
Users2,
15+
} from 'lucide-react';
16+
17+
import { cn } from '@/lib/utils';
18+
19+
import { Separator } from './ui/separator';
20+
21+
import { useState } from 'react';
22+
23+
import { TooltipProvider } from '@radix-ui/react-tooltip';
24+
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from './ui/resizable';
25+
import { Mail } from '@/lib/data';
26+
import { useMailStore } from '@/hooks/use-mail';
27+
import { SideNav } from './sideNav';
28+
import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs';
29+
import { Input } from './ui/input';
30+
31+
import { MailDisplay } from './mails/mail-display';
32+
import { MailList } from './mails/mail-list';
33+
34+
interface StickyDynamicNavProps {
35+
accounts: {
36+
label: string;
37+
email: string;
38+
icon: React.ReactNode;
39+
}[];
40+
mails: Mail[];
41+
defaultLayout: number[] | undefined;
42+
defaultCollapsed?: boolean;
43+
navCollapsedSize: number;
44+
}
45+
46+
export function StickyDynamicNav({
47+
accounts,
48+
mails,
49+
defaultLayout = [265, 440, 655],
50+
defaultCollapsed = false,
51+
navCollapsedSize,
52+
}: StickyDynamicNavProps) {
53+
const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);
54+
const { selected, selectMail } = useMailStore();
55+
const selectedMail = () => {
56+
return mails.find((item) => item.id === selected) || null;
57+
};
58+
59+
return (
60+
<TooltipProvider delayDuration={0}>
61+
<ResizablePanelGroup
62+
direction="horizontal"
63+
onLayout={(sizes: number[]) => {
64+
document.cookie = `react-resizable-panels:layout=${JSON.stringify(sizes)}`;
65+
}}
66+
className="h-full max-h-[800px] items-stretch"
67+
>
68+
<ResizablePanel
69+
defaultSize={defaultLayout[0]}
70+
collapsedSize={navCollapsedSize}
71+
collapsible={true}
72+
minSize={15}
73+
maxSize={20}
74+
onCollapse={() => {
75+
setIsCollapsed(true);
76+
document.cookie = `react-resizable-panels:collapsed=${JSON.stringify(true)}`;
77+
}}
78+
onExpand={() => {
79+
setIsCollapsed(false);
80+
document.cookie = `react-resizable-panels:collapsed=${JSON.stringify(false)}`;
81+
}}
82+
className={cn(isCollapsed && 'min-w-[50px] transition-all duration-300 ease-in-out')}
83+
>
84+
{/* Switcher here */}
85+
<div className={cn('flex h-[52px] items-center justify-center', isCollapsed ? 'h-[52px]' : 'px-2')}></div>
86+
87+
<Separator />
88+
<SideNav
89+
isCollapsed={isCollapsed}
90+
links={[
91+
{
92+
title: 'Inbox',
93+
label: '128',
94+
icon: Inbox,
95+
variant: 'default',
96+
},
97+
{
98+
title: 'Drafts',
99+
label: '9',
100+
icon: File,
101+
variant: 'ghost',
102+
},
103+
{
104+
title: 'Sent',
105+
label: '',
106+
icon: Send,
107+
variant: 'ghost',
108+
},
109+
// {
110+
// title: 'Junk',
111+
// label: '23',
112+
// icon: ArchiveX,
113+
// variant: 'ghost',
114+
// },
115+
{
116+
title: 'Trash',
117+
label: '',
118+
icon: Trash2,
119+
variant: 'ghost',
120+
},
121+
{
122+
title: 'Archive',
123+
label: '',
124+
icon: Archive,
125+
variant: 'ghost',
126+
},
127+
]}
128+
/>
129+
<Separator />
130+
<SideNav
131+
isCollapsed={isCollapsed}
132+
links={[
133+
{
134+
title: 'Social',
135+
label: '972',
136+
icon: Users2,
137+
variant: 'ghost',
138+
},
139+
{
140+
title: 'Updates',
141+
label: '342',
142+
icon: AlertCircle,
143+
variant: 'ghost',
144+
},
145+
{
146+
title: 'Forums',
147+
label: '128',
148+
icon: MessagesSquare,
149+
variant: 'ghost',
150+
},
151+
{
152+
title: 'Shopping',
153+
label: '8',
154+
icon: ShoppingCart,
155+
variant: 'ghost',
156+
},
157+
{
158+
title: 'Promotions',
159+
label: '21',
160+
icon: Archive,
161+
variant: 'ghost',
162+
},
163+
]}
164+
/>
165+
</ResizablePanel>
166+
<ResizableHandle withHandle />
167+
<ResizablePanel defaultSize={defaultLayout[1]} minSize={30}>
168+
<Tabs defaultValue="all">
169+
<div className="flex items-center px-4 py-2">
170+
<h1 className="text-xl font-bold">Inbox</h1>
171+
<TabsList className="ml-auto">
172+
<TabsTrigger value="all" className="text-zinc-600 dark:text-zinc-200">
173+
All mail
174+
</TabsTrigger>
175+
<TabsTrigger value="unread" className="text-zinc-600 dark:text-zinc-200">
176+
Unread
177+
</TabsTrigger>
178+
</TabsList>
179+
</div>
180+
<Separator />
181+
<div className="bg-background/95 p-4 backdrop-blur supports-[backdrop-filter]:bg-background/60">
182+
<form>
183+
<div className="relative">
184+
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
185+
<Input placeholder="Search" className="pl-8" />
186+
</div>
187+
</form>
188+
</div>
189+
<TabsContent value="all" className="m-0">
190+
<MailList items={mails} />
191+
</TabsContent>
192+
<TabsContent value="unread" className="m-0">
193+
<MailList items={mails.filter((item) => !item.read)} />
194+
</TabsContent>
195+
</Tabs>
196+
</ResizablePanel>
197+
<ResizableHandle withHandle />
198+
<ResizablePanel defaultSize={defaultLayout[2]}>
199+
<MailDisplay mail={selectedMail()} />
200+
</ResizablePanel>
201+
</ResizablePanelGroup>
202+
</TooltipProvider>
203+
);
204+
}

0 commit comments

Comments
 (0)