diff --git a/src/pages/Post.tsx b/src/pages/Post.tsx deleted file mode 100644 index 4c5b967..0000000 --- a/src/pages/Post.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import React, {FC} from 'react'; -// Routing -import {useParams, Link} from 'react-router-dom'; -import Routes from '../constants/routes'; -// Redux -import {compose} from '@reduxjs/toolkit'; -import {connect, useSelector} from 'react-redux'; -import {firestoreConnect, WithFirestoreProps} from 'react-redux-firebase'; -import {RootState} from '../store'; -import {selectProfile} from '../store/firebase'; -import Collections from '../constants/collections'; -// Typing -import Post from '../models/Post'; -import Comment from '../types/Comment'; -// Form -import useForm from '../hooks'; - -interface IProps extends WithFirestoreProps { - post: Post; -} - -/** - * Display a Post and the related comments. Shows a form to add a comment. - */ -const PostPage: FC = ({post, firestore}) => { - const {avatarUrl, displayName} = useSelector(selectProfile); - const newComment: Comment = { - name: displayName ?? 'error', - avatarUrl: avatarUrl ?? 'error', - text: '', - }; - - const {formData, handleChange, resetForm} = useForm(newComment); - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - - firestore - .update(`${Collections.POSTS}/${post.id}`, { - comments: [...post.comments, formData], - }) - .then(() => resetForm()) - .catch(err => console.error(err)); - }; - - return ( -
- - Back To Posts - - -
-
- - {post.name} -

{post.name}

- -
-
-

{post.text}

-
-
- -
-
-

Leave A Comment

-
-
- - -
-
- -
- {post.comments?.map((c: Comment, i: number) => ( -
-
- - {c.name} -

{c.name}

-
-
-
-

{c.text}

-
-
- ))} -
-
- ); -}; - -/** - * Container to fetch id params from thr URI and pass it to Profile page - */ -const PostPageContainer: FC = () => { - const {id} = useParams(); - const Component = compose( - firestoreConnect(() => [`${Collections.POSTS}/${id}`]), - connect(({firestore: {data}}: RootState) => ({ - post: data.posts && {...data.posts[id], id}, - })), - )(PostPage); - - return ; -}; - -export default PostPageContainer; diff --git a/src/pages/Post/Comments.tsx b/src/pages/Post/Comments.tsx new file mode 100644 index 0000000..9a946ca --- /dev/null +++ b/src/pages/Post/Comments.tsx @@ -0,0 +1,26 @@ +import React, {FC} from 'react'; +import Comment from '../../types/Comment'; + +interface IProps { + comments: Comment[]; +} + +const PostComments: FC = ({comments}) => ( +
+ {comments?.map(({name, avatarUrl, text}: Comment, i: number) => ( +
+ +
+

{text}

+
+
+ ))} +
+); + +export default PostComments; diff --git a/src/pages/Post/Display.tsx b/src/pages/Post/Display.tsx new file mode 100644 index 0000000..6cd7656 --- /dev/null +++ b/src/pages/Post/Display.tsx @@ -0,0 +1,24 @@ +import React, {FC} from 'react'; +// Routing +import {Link} from 'react-router-dom'; +import Routes from '../../constants/routes'; + +import Post from '../../models/Post'; + +const PostDisplay: FC<{post: Post}> = ({ + post: {name, userID, avatarUrl, text}, +}) => ( +
+
+ + {name} +

{name}

+ +
+
+

{text}

+
+
+); + +export default PostDisplay; diff --git a/src/pages/Post/Form.tsx b/src/pages/Post/Form.tsx new file mode 100644 index 0000000..020f91c --- /dev/null +++ b/src/pages/Post/Form.tsx @@ -0,0 +1,28 @@ +import React, {FC} from 'react'; + +interface IProps { + handleSubmit: (e: React.FormEvent) => void; + handleChange: (e: React.ChangeEvent) => void; + text: string; +} + +const PostForm: FC = ({text, handleChange, handleSubmit}) => ( +
+
+

Leave A Comment

+
+
+ + +
+
+); + +export default PostForm; diff --git a/src/pages/Post/index.tsx b/src/pages/Post/index.tsx new file mode 100644 index 0000000..e915efe --- /dev/null +++ b/src/pages/Post/index.tsx @@ -0,0 +1,84 @@ +import React, {FC} from 'react'; +// Routing +import {useParams, Link} from 'react-router-dom'; +import Routes from '../../constants/routes'; +// Redux +import {compose} from '@reduxjs/toolkit'; +import {connect, useSelector} from 'react-redux'; +import {firestoreConnect, WithFirestoreProps} from 'react-redux-firebase'; +import {RootState} from '../../store'; +import {selectProfile} from '../../store/firebase'; +import Collections from '../../constants/collections'; +// Typing +import Post from '../../models/Post'; +import Comment from '../../types/Comment'; +// Form +import useForm from '../../hooks'; + +import PostForm from './Form'; +import PostComments from './Comments'; +import PostDisplay from './Display'; + +interface IProps extends WithFirestoreProps { + post: Post; +} + +/** + * Display a Post and the related comments. Shows a form to add a comment. + */ +const PostComponent: FC = ({post, firestore}) => { + const {avatarUrl, displayName} = useSelector(selectProfile); + const newComment: Comment = { + name: displayName ?? 'error', + avatarUrl: avatarUrl ?? 'error', + text: '', + }; + + const {formData, handleChange, resetForm} = useForm(newComment); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + firestore + .update(`${Collections.POSTS}/${post.id}`, { + comments: [...post.comments, formData], + }) + .then(() => resetForm()) + .catch(err => console.error(err)); + }; + + return ( +
+ + Back To Posts + + + + + + + +
+ ); +}; + +/** + * Container to fetch id params from thr URI and pass it to Profile page + */ +const PostPage: FC = () => { + const {id} = useParams(); + const Component = compose( + firestoreConnect(() => [`${Collections.POSTS}/${id}`]), + connect(({firestore: {data}}: RootState) => ({ + post: data.posts && {...data.posts[id], id}, + })), + )(PostComponent); + + return ; +}; + +export default PostPage;