diff --git a/client/src/app/postSlice.ts b/client/src/app/postSlice.ts
index 30ff9c4..c298498 100644
--- a/client/src/app/postSlice.ts
+++ b/client/src/app/postSlice.ts
@@ -7,12 +7,14 @@ interface postSliceInterface {
status: Status;
followedPosts: Post[];
globalPosts: Post[];
+ aPost: Post | null;
}
const initialState: postSliceInterface = {
status: Status.idle,
followedPosts: [],
globalPosts: [],
+ aPost: null,
};
export const postSlice = createSlice({
@@ -28,6 +30,9 @@ export const postSlice = createSlice({
setGlobalPosts: (state, action) => {
state.globalPosts = action.payload;
},
+ setAPost: (state, action) => {
+ state.aPost = action.payload;
+ },
},
});
@@ -69,7 +74,29 @@ export const unLikePost =
dispatch(setStatus(Status.idle));
};
-export const { setFollowedPosts, setGlobalPosts, setStatus } =
+export const fetchAPost =
+ (postId: number): AppThunk =>
+ async (dispatch: any) => {
+ const postApi = createApi(store);
+
+ dispatch(setStatus(Status.loading));
+ const response = await postApi.getPost(postId);
+ dispatch(setAPost(response.data));
+ dispatch(setStatus(Status.idle));
+ };
+
+export const commentAPost =
+ (postId: number, comment: string): AppThunk =>
+ async (dispatch: any) => {
+ const postApi = createApi(store);
+
+ dispatch(setStatus(Status.loading));
+ await postApi.commentPost(postId, { content: comment });
+ dispatch(fetchAPost(postId));
+ dispatch(setStatus(Status.idle));
+ };
+
+export const { setFollowedPosts, setGlobalPosts, setStatus, setAPost } =
postSlice.actions;
export default postSlice.reducer;
@@ -77,6 +104,7 @@ export default postSlice.reducer;
export const selectFollowedPosts = (state: any) => state.post.followedPosts;
export const selectAllPosts = (state: any) => state.post.globalPosts;
export const selectStatus = (state: any) => state.post.status;
+export const selectAPost = (state: any) => state.post.aPost;
function createApi(store: Store) {
return new PostsApi(
diff --git a/client/src/components/appAvatar.tsx b/client/src/components/appAvatar.tsx
index 43b2fd6..8a41df9 100644
--- a/client/src/components/appAvatar.tsx
+++ b/client/src/components/appAvatar.tsx
@@ -3,6 +3,7 @@ import { User, UserWithRelations } from "../api";
interface AppAvatarProps {
user: User | UserWithRelations;
+ small?: boolean;
}
export function AppAvatar(props: AppAvatarProps) {
@@ -10,6 +11,10 @@ export function AppAvatar(props: AppAvatarProps) {
);
}
diff --git a/client/src/index.tsx b/client/src/index.tsx
index 4bd5348..d366174 100644
--- a/client/src/index.tsx
+++ b/client/src/index.tsx
@@ -14,7 +14,7 @@ import { Provider } from "react-redux";
import { store } from "./app/store";
import PostList from "./routes/postList";
import Profile from "./routes/profile";
-import Post from "./routes/post";
+import PostView from "./routes/post";
import NewPost from "./routes/newPost";
import Search from "./routes/search";
@@ -52,7 +52,7 @@ const router = createBrowserRouter([
},
{
path: "post/:id",
- element: ,
+ element: ,
},
{
path: "search",
diff --git a/client/src/routes/post.tsx b/client/src/routes/post.tsx
index b0a457c..06b636b 100644
--- a/client/src/routes/post.tsx
+++ b/client/src/routes/post.tsx
@@ -1,3 +1,134 @@
-export default function Post() {
- return <>Post>;
+import { useSelector } from "react-redux";
+import { useParams } from "react-router-dom";
+import { commentAPost, fetchAPost, selectAPost } from "../app/postSlice";
+import { useAppDispatch } from "../app/store";
+import { useEffect } from "react";
+import React from "react";
+import { Post } from "../api";
+import {
+ Box,
+ Button,
+ Divider,
+ Paper,
+ TextField,
+ Typography,
+} from "@mui/material";
+import { AppAvatar } from "../components/appAvatar";
+
+export default function PostView() {
+ const postId = useParams<{ id: string }>().id;
+ const storePost = useSelector(selectAPost);
+ const [postToDisplay, setPostToDisplay] = React.useState(null);
+ const [newComentText, setNewCommentText] = React.useState("");
+ const dispatch = useAppDispatch();
+
+ useEffect(() => {
+ dispatch(fetchAPost(parseInt(postId!, 10)));
+ }, []);
+
+ useEffect(() => {
+ setPostToDisplay(storePost);
+ }, [storePost]);
+
+ const handleCommentPost = () => {
+ if (newComentText.length > 0) {
+ dispatch(commentAPost(postToDisplay!.id!, newComentText));
+ setNewCommentText("");
+ }
+ };
+
+ const handleCancelComment = () => {
+ setNewCommentText("");
+ };
+
+ return (
+
+
+
+
+
+ {postToDisplay?.createdBy && (
+
+ )}
+
+ {postToDisplay?.createdBy?.firstName}{" "}
+ {postToDisplay?.createdBy?.lastName}
+
+
+
+ {postToDisplay?.title}
+ {postToDisplay?.content}
+
+
+
+
+ setNewCommentText(e.target.value)}
+ InputProps={{
+ endAdornment: (
+ <>
+
+
+ >
+ ),
+ }}
+ sx={{
+ mb: "1rem",
+ }}
+ />
+
+ {postToDisplay?.comments?.map((comment) => (
+
+
+
+
+
+ {comment.createdBy?.firstName} {comment.createdBy?.lastName}
+
+
+
+ {comment.content}
+
+
+ ))}
+
+
+
+ );
}