Skip to content

Commit 98178dc

Browse files
authored
Merge pull request #402 from CodebilityDev/miguel/feed-modal
miguel/ feed post to modal
2 parents 8533483 + 91007a9 commit 98178dc

4 files changed

Lines changed: 129 additions & 46 deletions

File tree

‎apps/codebility/app/home/feeds/_components/Post.tsx‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { useState } from "react";
12
import Image from "next/image";
23
import Link from "next/link";
4+
import FeedPostModal from "@/components/modals/FeedPostModal";
35
import { Box } from "@/components/shared/dashboard";
46
import { defaultAvatar } from "@/public/assets/images";
57
import { format } from "date-fns";
@@ -17,6 +19,8 @@ interface PostProps {
1719
}
1820

1921
export default function Post({ post, isMentor, onDelete }: PostProps) {
22+
const [isModalOpen, setIsModalOpen] = useState(false);
23+
2024
const handleDelete = async (e: React.MouseEvent) => {
2125
e.stopPropagation();
2226
e.preventDefault();
@@ -39,9 +43,14 @@ export default function Post({ post, isMentor, onDelete }: PostProps) {
3943
// You can add upvote logic here
4044
};
4145

46+
const openModal = () => setIsModalOpen(true);
47+
const closeModal = () => setIsModalOpen(false);
4248
return (
43-
<Link href={`/home/feeds/${post.id}`} passHref>
44-
<Box className="group relative flex h-[400px] cursor-pointer flex-col justify-between p-3">
49+
<>
50+
<Box
51+
className="group relative flex h-[400px] cursor-pointer flex-col justify-between p-3"
52+
onClick={openModal}
53+
>
4554
{/* Delete Button in top-right */}
4655
{isMentor && (
4756
<button
@@ -96,6 +105,11 @@ export default function Post({ post, isMentor, onDelete }: PostProps) {
96105
<PostUpvote post={post} />
97106
</div>
98107
</Box>
99-
</Link>
108+
<FeedPostModal
109+
isOpen={isModalOpen}
110+
onClose={closeModal}
111+
postId={post.id}
112+
/>
113+
</>
100114
);
101115
}

apps/codebility/app/home/feeds/[postId]/page.tsx renamed to apps/codebility/app/home/feeds/_components/PostView.tsx

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import type { PostType } from "../_services/query";
1616
import PostUpvote from "../_components/PostUpvote";
1717
import { getUserRole } from "../_services/action";
1818

19-
export default function PostPage() {
20-
const { postId } = useParams() as { postId: string };
19+
interface PostViewProps {
20+
postId: string;
21+
}
2122

23+
export default function PostView({ postId }: PostViewProps) {
2224
const [supabase, setSupabase] = useState<any>(null);
2325

2426
useEffect(() => {
@@ -92,48 +94,42 @@ export default function PostPage() {
9294

9395
return (
9496
<>
95-
<div className="mx-auto flex w-full max-w-[50rem] flex-col gap-4">
96-
<Box className="mx-auto w-full rounded-lg bg-white p-8 shadow-xl dark:bg-gray-800">
97-
<div className="container mx-auto flex flex-col gap-4 px-4 py-6 sm:px-6 lg:px-8">
98-
<h1 className="text-3xl font-bold">{post.title}</h1>
99-
<div className="flex items-center">
100-
<Image
101-
src={post.author_id?.image_url || defaultAvatar}
102-
alt={`${post.author_id?.first_name || "User"}'s profile`}
103-
className="mr-4 h-10 w-10 rounded-full object-cover"
104-
width={40}
105-
height={40}
106-
/>
107-
<div className="flex-1">
108-
<h2 className="font-semibold text-gray-800 dark:text-gray-100">
109-
{post.author_id
110-
? `${post.author_id.first_name} ${post.author_id.last_name}`
111-
: "Codebility"}
112-
</h2>
113-
</div>
114-
<p className="text-sm text-gray-500 dark:text-gray-400">
115-
{format(new Date(post.created_at), "MMM d, yyyy")}
116-
</p>
117-
</div>
118-
119-
<PostUpvote post={post} />
120-
121-
<img
122-
src={post.image_url || "/assets/images/bg-certificate.png"}
123-
alt="Post image"
124-
className="h-full w-full object-cover"
125-
/>
126-
<p className="mb-4 mt-4 text-justify text-gray-600 dark:text-gray-400">
127-
{post.content}
128-
</p>
129-
{isMentor && (
130-
<Button className="mb-4 mt-4 w-auto" onClick={openModal}>
131-
Edit Post
132-
</Button>
133-
)}
134-
</div>
135-
</Box>
97+
<h1 className="text-3xl font-bold">{post.title}</h1>
98+
<div className="flex items-center">
99+
<Image
100+
src={post.author_id?.image_url || defaultAvatar}
101+
alt={`${post.author_id?.first_name || "User"}'s profile`}
102+
className="mr-4 h-10 w-10 rounded-full object-cover"
103+
width={40}
104+
height={40}
105+
/>
106+
<div className="flex-1">
107+
<h2 className="font-semibold text-gray-800 dark:text-gray-100">
108+
{post.author_id
109+
? `${post.author_id.first_name} ${post.author_id.last_name}`
110+
: "Codebility"}
111+
</h2>
112+
</div>
113+
<p className="text-sm text-gray-500 dark:text-gray-400">
114+
{format(new Date(post.created_at), "MMM d, yyyy")}
115+
</p>
136116
</div>
117+
118+
<PostUpvote post={post} />
119+
120+
<img
121+
src={post.image_url || "/assets/images/bg-certificate.png"}
122+
alt="Post image"
123+
className="h-full w-full object-cover"
124+
/>
125+
<p className="mb-4 mt-4 text-justify text-gray-600 dark:text-gray-400">
126+
{post.content}
127+
</p>
128+
{isMentor && (
129+
<Button className="mb-4 mt-4 w-auto" onClick={openModal}>
130+
Edit Post
131+
</Button>
132+
)}
137133
<EditPostModal
138134
post={post}
139135
isOpen={isModalOpen}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"use client";
2+
3+
import PostView from "@/app/home/feeds/_components/PostView";
4+
import {
5+
Dialog,
6+
DialogContent,
7+
DialogHeader,
8+
DialogTitle,
9+
} from "@/components/ui/dialog";
10+
import { VisuallyHidden } from "@/components/ui/visuallyHidden";
11+
12+
interface FeedPostModalProps {
13+
isOpen: boolean;
14+
onClose: () => void;
15+
postId: string;
16+
}
17+
18+
const FeedPostModal: React.FC<FeedPostModalProps> = ({
19+
isOpen,
20+
onClose,
21+
postId,
22+
}) => {
23+
return (
24+
<Dialog
25+
open={isOpen}
26+
onOpenChange={(open) => {
27+
if (!open) onClose();
28+
}}
29+
30+
>
31+
<DialogHeader>
32+
<DialogTitle>
33+
<VisuallyHidden>Post</VisuallyHidden>
34+
</DialogTitle>
35+
</DialogHeader>
36+
<DialogContent className="flex max-w-2xl max-h-[80vh] flex-col overflow-auto">
37+
<PostView postId={postId} />
38+
</DialogContent>
39+
</Dialog>
40+
);
41+
};
42+
43+
export default FeedPostModal;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"use client";
2+
3+
import * as React from "react";
4+
import { cn } from "@/lib/utils";
5+
import { Slot } from "@radix-ui/react-slot";
6+
7+
export interface VisuallyHiddenProps
8+
extends React.HTMLAttributes<HTMLSpanElement> {
9+
asChild?: boolean;
10+
}
11+
12+
const VisuallyHidden = React.forwardRef<HTMLSpanElement, VisuallyHiddenProps>(
13+
({ className, asChild = false, ...props }, ref) => {
14+
const Comp = asChild ? Slot : "span";
15+
16+
return (
17+
<Comp
18+
ref={ref}
19+
className={cn(
20+
"absolute -m-px h-px w-px overflow-hidden whitespace-nowrap border-0 p-0",
21+
className,
22+
)}
23+
{...props}
24+
/>
25+
);
26+
},
27+
);
28+
VisuallyHidden.displayName = "VisuallyHidden";
29+
30+
export { VisuallyHidden };

0 commit comments

Comments
 (0)