Skip to content

Commit 12720f2

Browse files
committed
refactor: Make PostMenu reusable
1 parent c1f761c commit 12720f2

File tree

3 files changed

+105
-66
lines changed

3 files changed

+105
-66
lines changed

package-lock.json

Lines changed: 21 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import {
2+
DropdownMenu,
3+
DropdownMenuContent,
4+
DropdownMenuItem,
5+
DropdownMenuLabel,
6+
DropdownMenuSeparator,
7+
DropdownMenuTrigger,
8+
} from "@/common/components/ui/dropdown-menu";
9+
import { Button } from "@/common/components/ui/button";
10+
import React from "react";
11+
12+
export type MenuOption = {
13+
id: string;
14+
label: string;
15+
description?: string;
16+
condition?: (context: any) => boolean;
17+
disabled?: (context: any) => boolean;
18+
onClick: (context: any) => void;
19+
separatorBefore?: boolean;
20+
};
21+
22+
export interface GlobalDropdownMenuProps {
23+
options: MenuOption[];
24+
context?: any;
25+
label?: string;
26+
trigger?: React.ReactNode;
27+
}
28+
29+
export const GlobalDropdownMenu: React.FC<GlobalDropdownMenuProps> = ({
30+
options,
31+
context,
32+
label = "Actions",
33+
trigger = (
34+
<Button variant="ghost" size="icon">
35+
<span></span>
36+
</Button>
37+
),
38+
}) => {
39+
const visibleOptions = options.filter(
40+
(option) => !option.condition || option.condition(context)
41+
);
42+
43+
return (
44+
<DropdownMenu>
45+
<DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>
46+
<DropdownMenuContent>
47+
<DropdownMenuLabel>{label}</DropdownMenuLabel>
48+
{visibleOptions.map((option) => (
49+
<div key={option.id}>
50+
{option.separatorBefore && <DropdownMenuSeparator />}
51+
<DropdownMenuItem
52+
disabled={option.disabled?.(context)}
53+
onClick={() => option.onClick(context)}
54+
className="flex flex-col items-start cursor-pointer"
55+
>
56+
<p>{option.label}</p>
57+
{option.description && (
58+
<p className="text-sm text-gray-500 relative">
59+
{option.description}
60+
</p>
61+
)}
62+
</DropdownMenuItem>
63+
</div>
64+
))}
65+
</DropdownMenuContent>
66+
</DropdownMenu>
67+
);
68+
};

src/network/posts/post-menu.tsx

Lines changed: 16 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,23 @@
1-
import { Button } from "@/common/components/ui/button";
2-
import {
3-
DropdownMenu,
4-
DropdownMenuContent,
5-
DropdownMenuItem,
6-
DropdownMenuLabel,
7-
DropdownMenuSeparator,
8-
DropdownMenuTrigger,
9-
} from "@/common/components/ui/dropdown-menu";
101
import { EllipsisVertical } from "lucide-react";
112
import { Post } from "./post.types";
12-
13-
type MenuOption = {
14-
id: string;
15-
label: string;
16-
description?: string;
17-
condition?: (post: Post) => boolean;
18-
disabled?: (post: Post) => boolean;
19-
onClick: (post: Post) => void;
20-
separatorBefore?: boolean;
21-
};
3+
import { GlobalDropdownMenu } from "@/common/components/ui/global-dropdown-menu";
224

235
export const PostMenu = ({ post }: { post: Post }) => {
24-
const menuOptions: MenuOption[] = [
25-
{
26-
id: "dm",
27-
label: "Send a DM",
28-
description: `Ask about taking the job\nPost type: ${post.type}`,
29-
condition: (post) => true,
30-
disabled: (post) => false,
31-
onClick: (post) => {},
32-
separatorBefore: true,
33-
},
34-
];
35-
36-
const visibleOptions = menuOptions.filter(
37-
(option) => !option.condition || option.condition(post)
38-
);
39-
406
return (
41-
<DropdownMenu>
42-
<DropdownMenuTrigger asChild>
43-
<Button variant="ghost" size="icon">
44-
<EllipsisVertical size={24} />
45-
</Button>
46-
</DropdownMenuTrigger>
47-
<DropdownMenuContent>
48-
<DropdownMenuLabel>Post Actions</DropdownMenuLabel>
49-
50-
{visibleOptions.map((option) => (
51-
<div key={option.id}>
52-
{option.separatorBefore && <DropdownMenuSeparator />}
53-
<DropdownMenuItem
54-
disabled={option.disabled?.(post)}
55-
onClick={() => option.onClick(post)}
56-
>
57-
<p>{option.label}</p>
58-
{option.description && (
59-
<p className="text-sm text-gray-500">{option.description}</p>
60-
)}
61-
</DropdownMenuItem>
62-
</div>
63-
))}
64-
</DropdownMenuContent>
65-
</DropdownMenu>
7+
<GlobalDropdownMenu
8+
options={[
9+
{
10+
id: "dm",
11+
label: "Send a DM",
12+
description: `Ask about taking the job : Post type: ${post.type}`,
13+
condition: () => true,
14+
disabled: () => false,
15+
onClick: () => {},
16+
separatorBefore: true,
17+
},
18+
]}
19+
context={post}
20+
label="Post Actions"
21+
/>
6622
);
6723
};

0 commit comments

Comments
 (0)