Skip to content

Commit 8d5645d

Browse files
committed
feat(snippets): setup sidebar and main snippets layout
1 parent 161c451 commit 8d5645d

File tree

19 files changed

+1346
-30
lines changed

19 files changed

+1346
-30
lines changed

package-lock.json

Lines changed: 14 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@
1414
"@radix-ui/react-accordion": "^1.2.11",
1515
"@radix-ui/react-aspect-ratio": "^1.1.7",
1616
"@radix-ui/react-avatar": "^1.1.10",
17-
"@radix-ui/react-dialog": "^1.1.14",
17+
"@radix-ui/react-dialog": "^1.1.15",
1818
"@radix-ui/react-label": "^2.1.7",
1919
"@radix-ui/react-navigation-menu": "^1.2.13",
20+
"@radix-ui/react-select": "^2.2.6",
21+
"@radix-ui/react-separator": "^1.1.7",
2022
"@radix-ui/react-slot": "^1.2.3",
2123
"@radix-ui/react-switch": "^1.2.5",
24+
"@radix-ui/react-tooltip": "^1.2.8",
2225
"@types/mdx": "^2.0.13",
2326
"class-variance-authority": "^0.7.1",
2427
"clsx": "^2.1.1",
@@ -31,6 +34,7 @@
3134
"radix-ui": "^1.4.3",
3235
"react": "^19.1.0",
3336
"react-dom": "^19.1.0",
37+
"react-icons": "^5.5.0",
3438
"react-markdown": "^10.1.0",
3539
"react-syntax-highlighter": "^15.6.6",
3640
"remark-gfm": "^4.0.1",

src/app/globals.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@
108108
--chart-3: oklch(0.769 0.188 70.08);
109109
--chart-4: oklch(0.627 0.265 303.9);
110110
--chart-5: oklch(0.645 0.246 16.439);
111-
--sidebar: oklch(0.205 0 0);
112-
--sidebar-foreground: oklch(0.985 0 0);
111+
--sidebar: hsl(0, 0%, 11%);
112+
--sidebar-foreground: hsl(0, 0%, 90%);
113113
--sidebar-primary: oklch(0.488 0.243 264.376);
114114
--sidebar-primary-foreground: oklch(0.985 0 0);
115115
--sidebar-accent: oklch(0.269 0 0);
Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
import SnippetList from "@/components/layouts/snippet-list";
2+
13
export default function Categories() {
2-
return <p>Categories</p>;
4+
const sampleData = [
5+
{
6+
id: "truncate-string",
7+
category: "string-manipulation",
8+
title: "Reverse String",
9+
description: "Reverses the characters in a string.",
10+
languages: ["js", "cpp", "py"],
11+
contributors: ["technoph1le", "Vaibhav-kesarwani"],
12+
tags: ["string", "reverse"],
13+
},
14+
{
15+
id: "string-to-camel-case",
16+
category: "string-manipulation",
17+
title: "Convert String to Camel Case",
18+
description: "Converts a given string into camelCase.",
19+
languages: ["js", "java"],
20+
contributors: ["aumirza", "Mcbencrafter"],
21+
tags: ["string", "case"],
22+
},
23+
];
24+
25+
return (
26+
<section className="space-y-4">
27+
<h2 className="text-2xl font-bold">String Manipulation</h2>
28+
<SnippetList snippets={sampleData} />
29+
</section>
30+
);
331
}

src/app/snippets/layout.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1+
import SnippetHeader from "@/components/layouts/snippet-header";
12
import SnippetSidebar from "@/components/layouts/snippet-sidebar";
23

4+
import { SidebarProvider } from "@/components/ui/sidebar";
5+
36
export default function SnippetsLayout({
47
children,
58
}: {
69
children: React.ReactNode;
710
}) {
811
return (
9-
<main>
12+
<SidebarProvider>
1013
<SnippetSidebar />
11-
<section>{children}</section>
12-
</main>
14+
<main className="p-4 space-y-4 w-full">
15+
<SnippetHeader />
16+
{children}
17+
</main>
18+
</SidebarProvider>
1319
);
1420
}

src/app/snippets/page.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,27 @@
1+
import SnippetList from "@/components/layouts/snippet-list";
2+
13
export default function SnippetsPage() {
4+
const sampleData = [
5+
{
6+
id: "reverse-string",
7+
category: "string-manipulation",
8+
title: "Reverse String",
9+
description: "Reverses the characters in a string.",
10+
languages: ["js", "cpp", "py"],
11+
contributors: ["technoph1le", "Vaibhav-kesarwani"],
12+
tags: ["string", "reverse"],
13+
},
14+
{
15+
id: "string-to-camel-case",
16+
category: "string-manipulation",
17+
title: "Convert String to Camel Case",
18+
description: "Converts a given string into camelCase.",
19+
languages: ["js", "java"],
20+
contributors: ["aumirza", "Mcbencrafter"],
21+
tags: ["string", "case"],
22+
},
23+
];
24+
225
// This is for showing all the snippets
3-
return <h1>Hello</h1>;
26+
return <SnippetList snippets={sampleData} />;
427
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Search } from "lucide-react";
2+
import { Input } from "@/components/ui/input";
3+
import {
4+
Select,
5+
SelectContent,
6+
SelectItem,
7+
SelectTrigger,
8+
SelectValue,
9+
} from "../ui/select";
10+
11+
export default function SnippetHeader() {
12+
return (
13+
<section className="grid gap-4 md:grid-cols-[1fr_auto_auto]">
14+
<div className="relative">
15+
<div className="absolute left-2 top-1/2 transform -translate-y-1/2">
16+
<Search size={16} />
17+
</div>
18+
<Input
19+
placeholder="Search 875 snippets..."
20+
type="search"
21+
className="pl-8 w-full"
22+
/>
23+
</div>
24+
<Select>
25+
<SelectTrigger className="w-[10rem]">
26+
<SelectValue placeholder="Sort by" />
27+
</SelectTrigger>
28+
<SelectContent>
29+
<SelectItem value="relevance">Relevance</SelectItem>
30+
<SelectItem value="popularity">Popularity</SelectItem>
31+
<SelectItem value="recent">Most recent</SelectItem>
32+
<SelectItem value="oldest">The oldest</SelectItem>
33+
</SelectContent>
34+
</Select>
35+
<Select>
36+
<SelectTrigger className="w-[15rem]">
37+
<SelectValue placeholder="Filter by language" />
38+
</SelectTrigger>
39+
<SelectContent>
40+
<SelectItem value="js">JavaScript</SelectItem>
41+
<SelectItem value="py">Python</SelectItem>
42+
<SelectItem value="cplusplus">C++</SelectItem>
43+
</SelectContent>
44+
</Select>
45+
</section>
46+
);
47+
}

src/components/layouts/snippet-list.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import SnippetItem from "../ui/snippet-item";
22

33
import type { SnippetType } from "@/types";
44

5-
export default function SnippetList() {
6-
const snippets: SnippetType[] = [];
5+
interface SnippetListProps {
6+
snippets: SnippetType[];
7+
}
78

9+
export default function SnippetList({ snippets }: SnippetListProps) {
810
return (
9-
<ul>
11+
<ul className="grid gap-4 sm:grid-cols-3 md:grid-cols-4">
1012
{snippets.map((snippet) => (
11-
<SnippetItem snippet={snippet} />
13+
<SnippetItem key={snippet.id} snippet={snippet} />
1214
))}
1315
</ul>
1416
);
Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,124 @@
1+
import {
2+
Sidebar,
3+
SidebarContent,
4+
SidebarGroup,
5+
SidebarMenu,
6+
SidebarMenuButton,
7+
SidebarMenuItem,
8+
SidebarMenuSub,
9+
SidebarMenuSubButton,
10+
SidebarMenuSubItem,
11+
SidebarRail,
12+
} from "@/components/ui/sidebar";
13+
import Link from "next/link";
14+
15+
const categories = [
16+
{
17+
title: "Routing",
18+
url: "#",
19+
count: 23,
20+
},
21+
{
22+
title: "Data Fetching",
23+
url: "#",
24+
isActive: true,
25+
count: 86,
26+
},
27+
{
28+
title: "Rendering",
29+
url: "#",
30+
count: 34,
31+
},
32+
{
33+
title: "Caching",
34+
url: "#",
35+
count: 64,
36+
},
37+
{
38+
title: "Styling",
39+
url: "#",
40+
count: 98,
41+
},
42+
{
43+
title: "Optimizing",
44+
url: "#",
45+
count: 45,
46+
},
47+
{
48+
title: "Configuring",
49+
url: "#",
50+
count: 123,
51+
},
52+
{
53+
title: "Testing",
54+
url: "#",
55+
count: 56,
56+
},
57+
{
58+
title: "Authentication",
59+
url: "#",
60+
count: 87,
61+
},
62+
{
63+
title: "Deploying",
64+
url: "#",
65+
count: 234,
66+
},
67+
{
68+
title: "Upgrading",
69+
url: "#",
70+
count: 12,
71+
},
72+
{
73+
title: "Examples",
74+
url: "#",
75+
count: 56,
76+
},
77+
];
78+
179
export default function SnippetSidebar() {
2-
return <aside>Sidebar here</aside>;
80+
return (
81+
<Sidebar collapsible="none" className="border-r border-border">
82+
<SidebarContent>
83+
<SidebarGroup>
84+
<SidebarMenu>
85+
<SidebarMenuItem>
86+
<SidebarMenuButton asChild>
87+
<Link href="/snippets">All</Link>
88+
</SidebarMenuButton>
89+
</SidebarMenuItem>
90+
<SidebarMenuItem>
91+
<SidebarMenuButton asChild>
92+
<Link href="/snippets/categories">Categories</Link>
93+
</SidebarMenuButton>
94+
{categories.length ? (
95+
<SidebarMenuSub>
96+
{categories.map((item) => (
97+
<SidebarMenuSubItem key={item.title}>
98+
<SidebarMenuSubButton
99+
className="py-4"
100+
asChild
101+
isActive={item.isActive}
102+
>
103+
<Link
104+
href={item.url}
105+
className="flex items-center justify-between"
106+
>
107+
<span>{item.title}</span>
108+
<span className="text-muted-foreground">
109+
{item.count}
110+
</span>
111+
</Link>
112+
</SidebarMenuSubButton>
113+
</SidebarMenuSubItem>
114+
))}
115+
</SidebarMenuSub>
116+
) : null}
117+
</SidebarMenuItem>
118+
</SidebarMenu>
119+
</SidebarGroup>
120+
</SidebarContent>
121+
<SidebarRail />
122+
</Sidebar>
123+
);
3124
}

src/components/ui/input.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as React from "react"
2+
3+
import { cn } from "@/lib/utils"
4+
5+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6+
return (
7+
<input
8+
type={type}
9+
data-slot="input"
10+
className={cn(
11+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
13+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14+
className
15+
)}
16+
{...props}
17+
/>
18+
)
19+
}
20+
21+
export { Input }

0 commit comments

Comments
 (0)